如何在UUID之间进行选择,自动增量/序列键和数据库主键的顺序表?

我正在看这三种主要方法的利弊来提供数据库行的主键.

因此,假设我正在使用支持多种方法数据库,是否有一个简单的启发式来确定最适合我的选择?

如何分析/多个主人,性能要求,ORM使用,安全性和测试等考虑有哪些选择?

任何可能遇到的意想不到的缺点?

解决方法

的UUID

除非这些是在增加单调序列中产生的,否则它们会严重伤害/分散索引.对UUID生成支持因系统而异.虽然可用,但在大多数情况下,我不会使用UUID作为主要聚簇索引/ PK.如果需要,我可能会把它作为第二列,也许是索引,也许不是.

有人认为,UUID可用于安全地从任意数量的系统生成/合并记录.虽然UUID(取决于方法)通常具有很小的碰撞机会,但至少有一些外部输入或非常糟糕的运气可能会产生碰撞.我相信只有一个真正的PK应该在系统之间传输,我认为在大多数情况下我不会(或不应该)数据库生成的UUID.

自动增量/顺序键和序列表

这真的取决于数据库支持.一些数据库支持更灵活的序列,简单的“自动增量”.这可能是或可能不是可取的(或者可能是这种任务的简单方法,甚至是).序列表通常更灵活,但是如果需要这种“灵活性”,我将很乐意回去参观设计模式,特别是如果涉及使用触发器.虽然我不喜欢“限制ORM”,但也可能在选择“更简单”的自动增量或序列类型/数据库支持方面有所作为.

不管使用何种方法,当使用代理主键时,仍然需要将真正的主键标识并编码到模式中.

此外,我认为“通过暴露自动序列PK来进行安全性妥协”是由于不正确地暴露内部数据库属性而导致的.虽然处理CRUD操作非常简单,但我相信内部按键和外露键(例如漂亮的客户编号)有区别.

只是我的两美分.

编辑,附加回复Tim:

I think the generated vs. true PK question is a very good one and one I need to consider also. I’d like UUIDs in general to the points you make. My hesitation was in size vs. an int/long. Was not aware of potential indexing de-optimizations,which is a much bigger concern for me.

我不会真的担心的大小 – 如果UUID是最好的,那么这是最好的.如果不是,那不是.在整体方案中,一个int的额外的12byte可能不会有太大的区别. sql Server 2005支持newsequentialid UUID生成功能,以避免与正常的UUID生成相关联的碎片.该页面讨论一些.我相信其他数据库有类似的解决方案.

And by “encoded into the schema”,do you mean more than adding a uniqueness constraint?

是.主键不一定是唯一的[unique]约束.只使用代理PK并不意味着数据库模型应该受到损害:-)附加索引也可以用来覆盖等.

And by “distinction between”,are you saying that surrogate primary keys never leak out?

我最初的帖子中的措词很难.这不是“永远不会”,如果他们这样做,那么这是另一个问题.人们常常通过猜想的数字来抱怨不安全感 – 例如如果您的订单是23,那么可能有一个订单22和24等.如果这是您的“保护”和/或可能泄漏敏感信息,那么系统已经有缺陷. (分离内部和外部ids并不固有地解决这个问题,仍然需要身份验证/授权.但是,使用“连续ids”提出了一个问题 – 我发现将一个随机数编码到分布式URL中可以处理我的用例相当好.)

更多的是我真正想跨越的:只是因为代理PK ID恰好是8942并不意味着它是8942的顺序.也就是说,保持与“一些字段是内部只有db”设计,顺序“数字“可能在表面上完全无关(但在DB模型中完全支持),例如”#2010-42c“或对业务需求有意义.在大多数情况下,这是外露的数字.

I feel that sometimes the generated key is really the true primary key as other fields are mutable (eg. user may change email and username).

这可能是数据库中的情况,我不会争论这个声明.然而,再次认为代理PK是数据库内部的,只需确保只导出/导入可以被很好识别的元组.如果用户名/电子邮件可能会更改,那么这可能非常好地包括在创建帐户时分配的UUID,并且很可能是代理PK本身.

当然,与所有的一样,保持开放并适应模型的问题,而不是模型的问题:-)对于像twitter这样的服务,他们使用自己的数字生成模式.请参见Twitter’s new ID generation.与[某些] UUID生成不同,twitter的方法(假设所有服务器都正确设置)保证所有分布式机器/进程都不会生成重复的ID,只需要64位,并保持粗略的排序(最重要的位是时间戳). (twitter生成的记录数可能与本地要求无关;-)

快乐编码.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_no='LJCG001H' THEN dbo.ELTPNAME(a.fw_nu) ELSE d.fm_name END),e.fw_state_nm,f.fw_rmk_nm
if not exists(select name from syscolumns where name='tod_no' and id=object_id('iebo09d12')) alter table iebo09d12 add tod_no varchar(
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_nm,g.fa_name from LJSS007H a (nolock) Left join LJPA002H b (nolock) On a.pa_no =b.pa_no Left jo
要在 SQL Server 2019 中设置定时自动重启,可以使用 Windows 任务计划程序。下面是详细的步骤: 步骤一:创建批处理文件 打开记事本。 输入以下内容: net stop "SQL Server (MSSQLSERVER)" net start "SQ
您收到的错误消息表明数据库 'EastRiver' 的事务日志已满,导致数据库操作失败。要解决这个问题,可以按照以下步骤操作: 1. 备份事务日志首先,备份事务日志以释放空间: BACKUP LOG [EastRiver] TO DISK = N'C:\Backup\East
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标识ID,若不知道怎么查询数据库的标识ID, 打开SQL Server management studio,点击工具。选择SQL Server Profiler。 登录,登录成功后,如果有个默认弹窗,先取消 新建追踪 命名
--最新的解决方法 --先创建用户帐户,不进行授权,然后通过下面的SQL语句将该用户帐户关联至对应的数据库用户。优点是避免了重新授权的操作。 USE tempdbEXEC sp_change_users_login 'Update_One', 'iemis', &#3
命令: ALTER TABLE 表名 add 列名 数据类型 default 默认值 not null 例如: ALTER TABLE LJEL005H add el_req int default 15 not null
declare @i int set @i=340 while @i<415 begin set @i=@iʱ insert into LJWK007H select '2024','28','9110','3PTSD621000000
alter table LJSU002H add default (0) for su_totalamt with values
命令: 有默认值时用:alter table 表名 DROP 约束 alter table 表名 DROP COLUMN 列名 例如: alter table LJEL005H DROP COLUMN el_req 注意: 如果有默认值先删除约束,否则报错: --消息 5074,级别 16,状态 1
mysql报错Unknown collation: utf8mb4_0900_ai_ci 解决方案: 将文件内的所有 utf8mb4_0900_ai_ci 换成 utf8_general_ci utf8mb4 换成 utf8
SQL SERVER根据数据表的某个栏位查询另一个数据表符合条件的某个栏位的值,如果多行则合并为一张字符串形式 要在 SQL Server 中根据一个数据表的某个列查询另一个数据表符合条件的某个列的值,并将多行结果合并为一个字符串,可以使用 FOR XML PATH 子句来执行此操作。以下是一个示例
ALTER TABLE LJPA001H DROP CONSTRAINT DF_LJPA001H_pa_sex_1 ALTER TABLE LJPA001H ALTER COLUMN pa_sex VARCHAR(1)
DATEDIFF和DATEADD函数。DATEDIFF函数计算两个日期之间的小时、天、周、月、年等时间间隔总数。DATEADD函数计算一个日期通过给时间间隔加减来获得一个新的日期。要了解更多的DATEDIFF和DATEADD函数以及时间间隔可以阅读微软联机帮助。使用DATEDIFF和DATEADD函
select top 100 substring(qr_code,8,8) ,* from [LiuJun_PKh_lcfc_hf] --where right(ri,8) or substring(qr_code,8,8)=. select top 10 left(right(one_code,1
1、发现事务日志备份突然停止了 2、查看维护计划中的事务日志设置 3、发现备份任务中,事务日志需要指向的数据库不在 4、进入数据库属性 5、在选项中将恢复模式改为“完整”
select DB_ID('SBTERPDB')
您收到的错误消息表明数据库 'EastRiver' 的事务日志已满,导致数据库操作失败。要解决这个问题,可以按照以下步骤操作: 1. 备份事务日志首先,备份事务日志以释放空间: BACKUP LOG [EastRiver] TO DISK = N'C:\Backup\East