我有一个存储用户文件的表,例如图像。它有一个自动递增的主键,所以很容易通过url猜测下一个/上一个id是什么,例如mydomain/file/12
。虽然我有适当的安全措施来防止未经授权的用户访问其他人的文件,但我更喜欢使用更复杂的URL ID,这很难猜测。
这个表会有很多插入/删除操作,所以我坚持使用一个自动递增的id作为主键,而不是使用一个uuid作为主键,因为这会带来相关的性能问题。
所以我在考虑添加一个名为uuid的额外列,我可以用它来检索文件。虽然mysql文档声明uuid被设计为一个在空间和时间上全局唯一的数字,但我仍然需要在这个列上实现一个唯一的索引,因为没有数据库机制来防止冲突-如果它曾经发生过?
任何建议赞赏。
4条答案
按热度按时间shyt4zoc1#
如果你想坚持列是唯一的,那么就在它上面创建一个唯一的索引/约束。
这将防止手动插入和更新复制现有列,即使自动机制在“正常”插入上生成保证唯一的值。
也就是说,如果性能是最重要的考虑因素,那么您可能决定禁用“手动”插入并放弃唯一索引。这将是基于性能需要的折衷方案。
js4nwp542#
我也在想同样的事情。我继承了一个带有索引文本UUID的数据库,首先想到的是,如果你在文本UUID上有索引,你的写入速度会变慢,因为UUID是随机的,数据库需要弄清楚在哪里插入INDEX(也有索引大小的问题,等等)。为了防止不太可能发生的碰撞,您肯定需要一个唯一的索引,以下两种解决方案之一可能对您有用。
在拥有更复杂的URL方面,我认为像ULID这样的东西可能更适合你,因为它们是以某种顺序随机生成的。您可能要做的另一件事是存储和索引UUID in binary format。
bjp0bcyl3#
如果您对数据库上下文中的id选择感到满意,并且您只想确保序列id对URL和最终用户隐藏,那么我将使用类似
hashids
(https://hashids.org/)的东西将您的id转换为可以在URL中显示的字符串。另一方面,如果您想要全局唯一标识符的好处,但由于随机性带来的性能问题而没有使用全局唯一标识符作为主键,那么我会考虑设计一个考虑数据局部性的GUID。即
UUIDv7
或其类型版本typeid
(https://github.com/jetpack-io/typeid)关于你是否应该在
uuid
列中强制唯一性的问题,我的看法是,是的,应该这样做。如果没有它,数据库客户端就无法对两个具有相同UUID的不同记录执行INSERT语句。pftdvrlh4#
数据库将允许您添加没有索引的列(实际上并不需要),但是由于您希望查找特定/精确的值,因此您会发现应用程序的性能提升远远超过成本。
优点是索引只需要存储UUID和递增ID,而不需要存储实际的图像数据或任何其他元数据。这将允许INSERT的索引维护(这些值都应该是不可变的,因此不需要UPDATE维护)比UUID首先是主键的情况更有效,但仍然为您提供了索引查找的大部分好处。
在其他数据库中,可以通过调整索引填充因子来进一步优化索引维护成本。这将减少添加记录强制拆分为新页面的频率。但是,MySQL不支持此功能。