0

最近我写了一个小程序,没什么值得注意的,主要是为了测试一些我发现的新东西,这些东西并不真正适合当时的任何现实生活应用。其中之一是为我的 Hibernate 实体使用 UUID 而不是序列生成的(由底层 Oracle 数据库)ID。

我的一位同事认为这将是一个糟糕的设计,并且可能对系统本身(ID 不是由数据库提供,即失去控制)或性能(不生成 UUID,而是在数据库方面)产生负面影响,处理它们)。是否有任何观点支持这种说法,或者它是胡说八道吗?我的意思是,生成器是由 Hibernate 提供的,并不是有人认为这是一个好主意,而且摆脱序列似乎是一个很好的权衡,并不是说它们不好,更多的是它们感觉像是开销。

4

3 回答 3

2

如果您不喜欢序列(并且使用它们也有缺点,例如跨实例的可移植性),那么为什么不使用 Oracle 的 GUID?它还可以用于自动生成主键:

create table my_tab2
(
val1 raw(16) default sys_guid(),
val2 varchar2(100),
primary key(val1)
)
table MY_TAB2 created.
> insert into my_tab2 (val2) values ('A test val')
1 rows inserted.
> commit
committed.
> select * from my_tab2
VAL1                             VAL2                                                                                               
-------------------------------- ----------------------------------------------------------------------------------------------------
E8B47FA523673C97E040A8C014175791 A test val  

您甚至不必关心 PK 的填充方式(没有序列触发器或在插入中不断使用 seq.nextval)。只是看起来不太漂亮(我想这不是一个“好”的数字)。

此外,如果您依赖 Hibernate(或数据库之外的任何其他应用程序/系统)为表生成密钥,那么该表是感激的,100% 依赖于 Hibernate 或任何外部系统来进行持续维护和完整性。数据属于公司,而不是应用程序。在我看来,数据库层应该尽可能独立(在这种情况下,简单地使用 Oracle 的 sys_guid 而不是 Hibernate 生成的东西会增加数据层的独立性)。在这种情况下,这似乎微不足道,但为什么不首先使用 Oracle 提供的特性。

于 2013-10-14T13:45:52.777 回答
1

完全不使用数据库生成主键可能是使用 UUID 的原因:您可以部署应用程序的多个实例并在本地生成 ID,而无需全局协调器。使用全局协调器会降低您的可伸缩性。

如果您进行批量插入,UUID 可能是一个性能问题,因为它们均匀分布在密钥空间中,导致许多可能的尝试以确保密钥是唯一的。

根据您的数据库,您应该考虑针对 UUID 进行调整:Postgres 有一个 uuid 列,在 MySQL 中,您可能希望将其表示为二进制以避免 UTF8 开销。

UUID 的另一个好处:如果您将 ID 公开给前端/最终用户,他无法看到您的数据库中有多少对象,也无法猜测下一个 ID。

于 2013-10-14T11:48:14.180 回答
0

UIID 的大小是 INTEGER(11) 的许多倍,仅此一项就会对性能产生重大影响。我看不出有任何理由使用数据库中已经内置的设施。确实是您必须证明该课程的合理性,而不是您的同事。

于 2013-10-14T11:30:12.907 回答