因此,在我的一个学校项目中,我们必须为伪电子商务网站创建一个数据库。项目说明要求我们用Boyce-Codd普通形式实现我们的数据库,但我认为这种正常形式存在一些歧义。
我们假设我们实现了Users
这样的实体:
Users(*email, username, password, some_other_fields)
(注意:*
meens主键)
首先,如果我理解BCNF,这个实体不是BCNF。如果username
是唯一的以及email
s,那么我们也可以像这样定义这个实体:
Users(*username, email, password, some_other_fields)
我的第一个问题是如何以Boyce-Codd普通形式创建此实体?
然后我对这个BCNF表单有另一个问题:缺少id
。假设用户可以更改其用户名和电子邮件。主键也将改变。我的问题是我没有真正的时间常量来定义我的实体中的元素。这意味着,例如,有关日志记录的一些问题:假设我们使用主键记录来自用户的操作,如果foo@smth.com
将其电子邮件更改为foo2@smth.com
,我们可以拥有此类日志:
[foo@smth.com] : action xxx
[foo@smth.com] : action yyy
[foo2@smth.com] : action zzz
然后,如果我们没有抓住电子邮件更改,我们所有的先例日志都没有意义:我们不知道谁是foo@smth.com
。
然后,我的第二个问题是你认为使用时间常量id(例如整数)更安全吗?
答案 0 :(得分:2)
BCNF的独特性是不够的。 BCNF强调功能依赖性。也就是说,属性是否依赖于功能键。
在这种情况下,属性不能依赖于电子邮件。电子邮件可以被其他人更改,不活动,回收。因此,独特并不足以成为候选键。如果功能限制用户名更改,则用户名可能具有更高的可靠性。
功能依赖性本质上取决于功能设计。如果您正在创建表的应用程序假定永远不允许更改用户名,则属性可以取决于用户名作为候选键。如果功能设计允许更改用户名,那么您需要引入或组合一个既独特又功能可靠的密钥。
如果引入了额外的独特ID,它们本身就不具备这些特性。更多'安全'比这里的用户名。但他们觉得'或者'成为'安全,因为大概功能和功能设计不希望id被改变。同样,如果您的功能设计允许更改ID,那么这将不会保持安全。最终,这一切都取决于您的功能,要求以及您的属性如何根据功能规范进行操作。
如果您必须考虑引入ID,对用户名的可靠性不满意,那么请考虑更多的GUID,而不是int / integer,原因如下: