管理用户数据的正确方法是什么?

Pie*_*rre 3 mysql performance database-design php

我正在尝试使用用户配置文件创建一个简单的注册登录脚本,我创建了一个具有以下结构的表:

+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| id         | int(11)       | NO   | PRI | NULL    | auto_increment |
| username   | varchar(32)   | NO   |     | NULL    |                |
| password   | varchar(32)   | NO   |     | NULL    |                |
| first_name | varchar(50)   | NO   |     | NULL    |                |
| last_name  | varchar(50)   | NO   |     | NULL    |                |
| email      | varchar(1024) | NO   |     | NULL    |                |
| active     | int(1)        | NO   |     | 0       |                |
+------------+---------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

我应该如何存储其他数据,例如:

country, user level, registration date, domain name, email activation key, last login date, and so on ...
Run Code Online (Sandbox Code Playgroud)

我有 2 个选项(也许还有更多我不知道的选项):

  • 创建这些作为此表中的列

  • 创建另一个与用户 ID 相关的表

我的问题是:

  • 如果以后我想添加更多要存储的数据,哪个更好?
  • 如果我对一个表采取第一种方法,如果我们已经有活跃用户,那么在稍后添加更多列时会出现问题吗?
  • 如果我们采用第二种方法,我应该如何构造数据表?

谢谢。

更新:

您如何看待 WordPress 在这件事上的方法?WordPress 有一个具有这种结构的 usermeta 表?

+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| umeta_id   | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id    | bigint(20) unsigned | NO   | MUL | 0       |                |
| meta_key   | varchar(255)        | YES  | MUL | NULL    |                |
| meta_value | longtext            | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

那么您如何看待这种存储用户数据的方式?是否应该在拥有大量用户的应用程序中考虑这一点?

小智 7

这是一个很好的“方法不止一种”的问题。

首先考虑您的数据使用情况:

考虑哪些字段将被更频繁地读取和写入。

例如,名字和姓氏可能只写一次并且很少更改,但根据您的应用程序,它们可能会被经常读取。

上次登录日期可能会频繁写入,您可能希望保留每个登录日期。

诸如激活密钥和注册日期之类的内容,取决于您的应用程序中的身份验证工作方式,可能会被写入一次,然后很少被读取。

您还应该考虑同时提取哪些数据,并尝试进行非规范化以使这些读取速度更快。例如,如果您总是将用户名、密码和名字放在一起(但没有其他联系信息),请将名字也放在登录表中。也就是说,如果这些数据很大,请考虑避免连接,并善待自己。

还要考虑哪些字段可能在查询的“where”子句中,并为这些字段建立索引。

这是我可以做到的一种方法:

联系表 (一次插入,很少更新,多次读取)

+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| user_id    | int(11)       | NO   | PRI | NULL    | auto_increment |
| first_name | varchar(50)   | NO   |     | NULL    |                |
| last_name  | varchar(50)   | NO   |     | NULL    |                |
| address    | varchar(50)   | NO   |     | NULL    |                |
| city       | varchar(50)   | NO   |     | NULL    |                |
| state      | varchar(50)   | NO   |     | NULL    |                |
| country    | varchar(50)   | NO   |     | NULL    |                |
| email      | varchar(1024) | NO   |     | NULL    |                |
+------------+---------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

登录表 (一次插入,可能是更新,多次读取;需要在登录时回显 first_name)

+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| user_id    | int(11)       | NO   | PRI | NULL    |                |
| username   | varchar(32)   | NO   |     | NULL    |                |
| password   | varchar(32)   | NO   |     | NULL    |                |
| first_name | varchar(50)   | NO   |     | NULL    |                |
+------------+---------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

登录历史表 (多次写入,每个 user_id 多个条目)

+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| user_id    | int(11)       | NO   | MUL | NULL    |                | 
| last_login | timestamp     | NO   | MUL | NULL    |                |
+------------+---------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

签到表 (一次写,很少读)

+------------------+---------------+------+-----+---------+----------------+
| Field            | Type          | Null | Key | Default | Extra          |
+------------------+---------------+------+-----+---------+----------------+
| user_id          | int(11)       | NO   | PRI | NULL    |                |
| registration_date| timestamp     | NO   |     | NULL    |                |
| activation_key   | varchar(50)   | NO   |     | NULL    |                |
+------------------+---------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

  • 很不错的分析。我唯一要补充的是,您还需要用户名或用户名/密码的唯一索引。您当然不希望任何人能够使用相同的用户名和密码组合登录多个帐户。 (3认同)