请发表意见-将遗留数据库从char(14)pks切换到int

bqf10yzr  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(178)

我正在管理一个支付处理系统的mysql数据库。出于各种遗留原因,它最初是使用char(14)为许多主键构建的,这些主键存储基于识别数据类型的前缀的序列id,后跟表示序列中大量数字的base36编码字符串,例如。
“pa00003nfmwhmq”转换为“付款286103946050”
这里的优点是仍然是顺序的半唯一键,缺点是用于聚集索引和非聚集索引的值都很大,降低了连接和查找速度,并且需要额外的内存/存储。
我正在考虑在发布api之前将它们全部迁移到整数,尽管我也喜欢惟一性。我也对过早的优化持谨慎态度。
我不是在寻找一个明确的答案,只是一些有经验的意见。
谢谢!

irlmq6kh

irlmq6kh1#

我的第一个想法是“无论如何,为了向后兼容,你必须挂起这个id吗?”像你这样有意义的id,倾向于在外部系统中存储和引用。最后会得到一个表,它有一个内部使用的整数主键和一个 char(14) 旧id和两个索引?这可能仍然是一种进步,但它影响到这种改变是否值得。在我接下来的评论中记住这一点。
如果您可以完全切换到自动递增整数,并摆脱特殊的id生成代码,那肯定会使事情更简单,插入速度更快。你需要多简单,多快来决定。只是在创建代码的某个地方有一个额外的函数没有困扰任何人吗?或者它会影响到所有地方的代码和设计吗?
…缺点是用于聚集索引和非聚集索引的值都很大,降低了连接和查找速度,并且需要额外的内存/存储。
与任何性能声明一样,首先要调查它们是否真实。是一个 char(14) 键真的会减慢连接速度并消耗内存和存储空间吗?
char(14) (14字节)并不比整数(4字节)大多少。每行额外的10字节仅为每百万条记录10 mb。但那只是为了储存钥匙。每个引用再加10个字节。每一个索引包含10多个字节。不过,如果不进行测量,我不会认为这是一个主要的存储和内存问题。
磁盘和内存通常比开发时间便宜得多。这并不意味着浪费,但要考虑节省几场演出是否值得,无论这可能需要多长时间(以及测试)。或者你可以买一个更大的磁盘和更多的内存。例如,我有一个项目可以受益于使用枚举字段而不是字符串。但我并不担心,因为这意味着开发人员有更多的时间来进行更改,并维护enum字段。相反,购买额外的磁盘还是比较便宜的。这可能会改变,当它改变的时候我会重新考虑。
类似于连接。如果它们被编入索引,那么不管它是否是 char 或者 int . 但你需要测试。
我建议您制作一个经过清理的数据库副本,或者使用您的测试工厂生成一个大小合适的副本,并使用 char(14)int . 一定要测试现实,以及这种变化是否会对性能产生真正的影响。仅仅运行简单的sql查询可能会让您对它们对性能的影响有一个很大的印象。同时调用您在生产中使用的实际函数,它们可能会淹没任何sql影响。
“pa00003nfmwhmq”转换为“付款286103946050”
我正在考虑在发布api之前将它们全部迁移到整数
向外界公开主键(或任何其他实现信息)具有安全性和兼容性考虑。攻击者可以使用它的知识,例如他们可以预测下一个密钥是什么。别这么做。
相反,为每个要公开的东西分配一个随机的api id,比如uuidv4(不要使用mysql的uuid函数,它是可以猜测的uuidv1)。将它们存储为 binary(16) 如果太空是个大问题。
那么你的主键是什么就不重要了。你可以随时改变你的设计。
这里的优势是一个半唯一的密钥仍然是顺序的。。。
这是个难题。主键必须是唯一的,所以我不知道你说的“半唯一”是什么意思。你是说隔着table吗?列a中的行的id可能与列b中的行是唯一的?如果是这样,请考虑uuid主键。或者考虑这是否真的是一个优势,你可以真正使用,因为半部分。

相关问题