用户数据库的设计
软件工程的老师上课说数据库中的用户数据表的主键要用自增的user_id
做主键,而不要用username
做主键。
这让我产生了一些疑问。
首先,用户登录时提供的账号信息必然是自选的字符串username
,而不是整数类型的自增主键user_id
。
我认为username
与user_id
其实都是具有唯一性约束的字段。因此username
完全可以替代user_id
的作用,所以user_id
就显得没那么有必要了。
如果没有其他足够的理由(比如优化之类的,可能我还不知道这个理由)是不应该引进这么个“多余”的字段的。
带着这样的疑问,我询问了老师这么做的原因。
老师给出了这样的回答,节省存储。
因为用户的主表只是存储用户的基本信息,其他用户表需要以用户主表的主键作为外键来存储信息。
这么说来,的确是这个样子的。
使用INTEGER UNSIGNED
类型来存储user_id
作为用户分表的外键,比起使用VARCHAR
类型的username
做外键,显然要节省存储的多。
毕竟前者只占用4个字节的存储,而后者占用username
长度+1个字节的存储,显然不会有几个人的username
会设置成3个字母以内嘛。
而且,数据越多,数据表越多,节省的存储也就越大。
理由很充分嘛。于是我继续问老师还有没有别的原因,他没再回答。
但是我觉得原因肯定不仅仅是这个,毕竟大部分应用和算法都是以空间换时间。
以user_id
应该有某种效率上的优势才对,虽然我现在认为看起来反而使用user_id
效率反而应该低些。
理由是:用户登录提供的是username
,因此,如果用户主表是以user_id
作为主键,那么应用需要通过登录用户提供的username
在用户主表中查询出user_id
,然后在用户分表中通过在用户主表查询出来的user_id
来查询用户其他相关信息。
而如果直接采用username
的话,不需要在用户主表做查询了,直接就可以拿着username
在各种用户分表查各种用户信息。
当然,上面的理由其实都是我的一种猜测而已,正确的学习习惯是学习不能够想当然,因此,猜测归猜测,终归还是要验证的。
我只好找了一位已在工作中的前辈(外校的一个学长,帮助我解决了许多问题)询问这个问题。
在我与他的讨论中,他给出了如下的回答:
- 老师说的没错,确实是能够节省存储
- 通常实践中也确实是使用整数类型的
user_id
来做主键的 - 整数字段做主键更加易于分表
- 自增主键比起字符串做索引,效率更高(看,果然有效率的问题哈)
username
这个东西过于偏向业务,如果今后系统还需要允许邮箱登录,手机号登录呢?
以上的回答我认为第3,4,5点是非常重要的原因。
3,4的原因可以归结为在效率上和分表操作性上确实比用username
做主键要好;
5则说明了对于那种扩展登录的业务,使用里面任何一种登录方式的字段作为主键都不太合适。