我有一个64位整数时间戳和斯汀用户名组合成一个字符串,并最终存储到数据库列。 撇开我为什么不能将它们存储在适当的类型的列,我的问题是如何将它们结合起来,充分利用基础数据库更好的性能。 这将是SQLite的和PostgreSQL或MySQL,目前还不能确定。
我想象,他们将使用B树为指标,这将是坏Concat的像(时间戳的用户名),因为时间戳一般会一直进步和树需要平衡经常。 用户名时间戳都要好得多,但还是每个用户记录将与每一个新条目增加。 我当时就想,也把时间戳和位的顺序相反。
我还能做什么? 一些聪明的异或什么? 什么是合理的模式最好? 数据永远不会被要求准确生成的字符串,没有范围和这样的访问。
唯一的要求是具有以两种方式生成的字符串和源数据之间相对快速的转换。
UPDATE:请家伙,我正向信息是什么样的字符串将用于存储作为主键到数据库(sqlite的,MySQL和PostgreSQL之一)更好。 答案或许是,它并不重要,或依赖于数据库引擎。 我没有跟我使用的架构或缓存解决方案的一个特殊问题。 我只是询问是否有任何的提升空间,以及如何。 我会明白一些对话题的答案。
UPDATE2:伟大的答案仍然没有明确的对我说: 不加柱,使塔上的B-tree索引不平衡? https://stackoverflow.com/a/2362693/520567
有一个在你的问题中的矛盾,你指定你不能割裂开来,并将它们存储在单独的列,但随后你在谈论分别索引两个部分 - 你不能做到这一点,不要把他们。
我可以看到你真的有两个选择:
- 在单独的列存储它们
- 散列输出降低索引存储器占用
理想情况下,你应该把它们存储在两列,并创建一个综合指数,如果你将他们以相同的顺序总是搜索在一起。 在这种情况下,其很难给出准确的建议先给予更多信息 - 但是一般的用户名,时间戳将使逻辑上,如果你每用户查询,或逆转,如果你想通过时间戳查询。 如果你需要在一个或其他搜索您还可以创建每个列的索引。
哈希您生成的字符串
INSERT INTO table (crc_hash_column, value_column_name)
values (CRC32(@generated_value), @generated_value)
会降低尺寸为32位整数(仅每行索引的4字节),比所需要的equilivant VARCHAR或CHAR索引空间小得多。
如果采取这种方式,那么你应该采取措施避免碰撞,由于生日悖论就会出现这种情况,而且更有可能为您的数据集的增长。 即使有冲突额外的过滤仍将给出的指数比其它的尺寸产生更高的性能。
SELECT * FROM table
WHERE crc_hash_column = CRC32(@search_value)
AND value_column_name = @searchvalue
使用哈希会造成一些更多的CPU周期 - 但CRC32验证是非常快所以即使你在每次搜索这些额外的工作是微小的给定了索引大量数据的好处时老调重弹。
一般来说,我宁愿第一个选项,但它几乎是不可能不知道您的使用情况来建议。
你就应该剖析这两个选项,看看是否符合您的要求。
那你说,你不能让他们在单独的列(你甚至不能建立一个新表以1:1的关系/镜像中的数据,以物化视图与触发器的视图/替换校正表中现有的表结构???? !!!!)意味着任何解决方案将是一个丑陋的黑客。
是的,这是多么的数据变化和结构如何影响更新的效率。 但是指数的目的是为了加快检索 - 你给了我们没有关于数据是如何访问/它是如何可能改变的信息。
我当时就想,也把时间戳和位的顺序相反
为什么? 这是更可能加快索引碎片不是减少。
MariaDB的支持虚拟列 - 和虚拟列的索引,因此你可以像扔规范化规则窗外愚蠢的事情 - 但如果你不能在架构则更换DBMS解决一个小问题可能不会成为要么非常实用的解决方案。
坦率地说,它是否值得花费时间和金钱开发一个坏的解决方案,已经花费尽可能妥善解决的问题,将有可能招致未来的成本,然后选择坏的解决方案是既浪费时间和金钱。