【问题标题】:MySQL gender table fieldMySQL 性别表字段
【发布时间】:2012-03-21 00:03:05
【问题描述】:

如果我想在我的表中创建一个性别字段,我如何确保我的数据库不接受除“M”或“F”之外的任何值?

 $sqlCommand = "CREATE TABLE members (
             id int(11) NOT NULL auto_increment,
             ... 
             ...
             ...
             ...
             gender
             )";

谢谢

【问题讨论】:

标签: mysql


【解决方案1】:

没有triggers、没有enums或其他恶魔活动。

您可以将FOREIGN KEY 用于只有 2 行的引用表:

CREATE TABLE Gender_Ref 
(   gender CHAR(1) NOT NULL,
    PRIMARY KEY (gender)
) ENGINE = InnoDB ;

INSERT INTO Gender_Ref (gender)
    VALUES
        ('F'), ('M')  ;

CREATE TABLE members 
(   id int(11) NOT NULL auto_increment,
     ... 
     ...
    gender CHAR(1) NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY gender
        REFERENCES Gender_Ref (gender)
) ENGINE = InnoDB ;

“锁定”引用表也是一个不错的建议,这样应用程序代码就只有读取权限。 (这通常适用于大多数参考表,如果您有一个 Admin 应用程序,您当然可以授予它对参考表的写入权限)。

【讨论】:

  • 尽管我不喜欢 ENUM 的(误)使用,但“性别”是可以合理考虑 ENUM 的情况。就我个人而言,我觉得它使 db/code/etc 更容易遵循并且比您提出的查找表解决方案更直观。
  • 对于这种简单的情况,我也会考虑使用 Enums。并解雇他们:)
  • 啊,但是如果您想稍后添加更多性别,这是更简单的选择,因为它不需要更改架构。 :)
【解决方案2】:

就像 cmets 中指出的那样,您可以像这样使用ENUM

gender ENUM('F','M') NOT NULL

但是,您必须小心,因为它仍然会接受空字符串(尽管您会收到警告):

mysql> create table t (g enum('M','F') not null);
Query OK, 0 rows affected (0.12 sec)

mysql> insert into t values ('M');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t values ('');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'g' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)

mysql> select * from t;
+---+
| g |
+---+
| M |
|   |
+---+
2 rows in set (0.00 sec)

为确保不会发生这种情况,您可以考虑将sql_mode (http://dev.mysql.com/doc/refman/5.5/en/server-sql-mode.html) 设置为更具限制性的值:

mysql> set sql_mode = strict_all_tables;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values ('');
ERROR 1265 (01000): Data truncated for column 'g' at row 1

但是,您应该调查这是否适合您。许多现有的应用程序(wordpress 等)不喜欢弄乱 sql_mode,所以如果你的代码是那些系统的插件,你想避免设置它。

您可以选择设置 sql_mode 服务器范围或会话范围;第一个选项会更健壮,但需要以非默认方式配置 MySQL,并且可能会影响其他应用程序。打开连接后立即在会话级别设置应该可以正常工作,但会使您的应用程序代码混乱。选择你的毒药。

ypercube 的使用外键的建议也很好,并且比 ENUM 更容易移植到其他 RDBMS。但是,您必须确保您的表都由 InnoDB 引擎管理。这正变得越来越标准,所以这不是一个糟糕的选择。

(如果你真的很偏执,你应该确保应用程序只有对性别参考表的读取权限)

【讨论】:

  • Thnx,我会在我的回答中添加那个(偏执狂:)建议。
  • Heh :) 坦率地说,我应该补充一点,类似的事情适用于 ENUM 解决方案:不应允许应用程序用户更改表的定义(尽管通常应用程序往往没有旋钮可做随机表定义更改,而它们确实具有通用表独立数据访问的设施,这是完全可行的)
【解决方案3】:

您可以使用enum 输入enum('M','F')

【讨论】:

    【解决方案4】:

    您可以使用触发器来检查它是否是 coreect 或者您可以使用枚举类型enum('M','F')

    【讨论】:

    • 我强烈建议不要使用触发器,原因有几个。请告诉我,一旦检测到无效值,您会在触发器内做什么?您将如何防止更新或插入发生?在 MySQL 5.5 中有一个适当的解决方案,但在早期版本中没有。
    猜你喜欢
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    相关资源
    最近更新 更多