是否建议在数据库的所有表中使用文本字段作为userID?

时间:2014-06-22 17:48:56

标签: mysql database database-design indexing primary-key

我看了一下ownCloud的数据库方案,并且有一个供所有用户使用的表 userID(他们的PK?)是用户名,他们没有数字ID或userID列。

这是以某种方式推荐的还是他们为什么这样做呢? 因为当我想更改用户的用户名时,我必须更改数据库的所有表中的所有受影响的行,而不只是更改users表中的一行。

在我看来,这是错误的,对表现不利。 https://github.com/owncloud/core/issues/9136 https://github.com/owncloud/core/blob/master/db_structure.xml#L1026他们的uid是text,其长度为64,但应该是integer字段,例如auto_increment

这是否是专业/良好实践?

也参考:Is it bad to use user name as primary key in database design?

3 个答案:

答案 0 :(得分:2)

首先......数字是存储内存的最佳选择 第二......名字可能重复!(重复)! 所以......数字是最好的

答案 1 :(得分:1)

它的专业性和良好做法都不会导致userID (their PK?) is the username

除索引和存储标准外;首先它令人困惑,如果它拥有用户名,那么列名必须反映相同。

第二,使其成为PK(如果有的话);您不允许存在可能存在同名用户的重复名称。

始终建议将列用作PK,以便唯一地确定其他字段。 username不应该被指定为PK,因为它可能有副本。

修改

不建议使用字符串作为主键,因为它需要更多的空间(取决于大小),并且它上面的索引比较会比较慢,因为它比计算密集的任务要好。但无论如何,如果场景要求字符串列为PK,则应该是它。

从您提供的GitHub link,表结构的index part(您正在谈论的)如下所示

<index>
<name>pref_userid_appid_key_index</name>
<primary>true</primary>
<unique>true</unique>
<field>
<name>userid</name>
<sorting>ascending</sorting>
</field>
<field>
<name>appid</name>
<sorting>ascending</sorting>
</field>
<field>
<name>configkey</name>
<sorting>ascending</sorting>
</field>
</index>

注意索引声明部分;从哪个表结构可以描述为

create table preferences (
userid text(64) not null,
appid text(32) not null,
configkey text(64) not null,
configvalue clob null,
constraint pref_userid_appid_key_index primary key(userid,appid,configkey)

可以看出,他们将userid,appid,configkey声明为PK,使其成为composite primary key非常有效,并确保所有记录的唯一标识。

希望这有助于清除您的理解。

答案 2 :(得分:1)

将用户名作为主键是完全可以的。用户名不应随时更改;它是用户在系统中使用的ID。它是标识系统中用户的内容,因此这是自然密钥,应该用作主键。除了一个例外:如果您决定拥有一个包含技术密钥(ID)的数据库,那么您将创建一个用户ID,并将用户名作为仅具有唯一约束的数据列。

使用技术密钥而不是自然密钥的数据库并不比另一个更好或更差。它只是一个不同的概念。是的,索引和连接的整数ID可能比字符串更快。这对技术ID来说是个加分。另一方面,使用自然键在数据库中需要更少的连接。为了询问&#34;给我用户MyName发布的所有消息&#34;,您只需从基于自然密钥的数据库中的消息表中进行选择,而在基于技术密钥的数据库中,您必须首先访问用户表。获取所需的用户ID以解释消息记录。

也可以在数据库中混合这两个概念,因为它显然是在给定的数据库中完成的。 jobs表具有ID,而users表使用用户名。这并不罕见。具有自然键的数据库有许多优点,但通常您希望使用代码。例如:国家/地区名称是唯一的,因此它似乎是国家/地区表的完美主键。但是,一个国家可以重新命名;缅甸和缅甸是同一个国家,只有更名。因此,可以使用国家/地区的ID来更轻松地进行重命名。与工作相同。那么,对于国家,您可以找到可以使用的ISO代码。对于你可能不会的工作,所以你创建了一个代码。因此,自然密钥数据库和技术密钥数据库都将使用作业表的ID。这里唯一(小)差异:在具有自然键的数据库中,您可以向用户显示ID;它是您可以与db一起使用的官方唯一代码。在具有技术ID的数据库中,通常不会向用户显示ID。它们只是技术小工具,除了作为存储关系的方式之外没有任何意义。