在包含值列表的许多列中使用ENUM数据类型是一种很好的做法吗?

时间:2015-05-31 08:20:11

标签: mysql database-design enums

我正在开发一个约会网站。在那个项目中,我使用一个名为“users”的mysql表,对于这个表,我使用了许多列的ENUM数据类型。

我的“用户”表格如下所示:

CREATE TABLE IF NOT EXISTS users (
    user_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    country_id SMALLINT UNSIGNED NOT NULL,

    username VARCHAR(20) NOT NULL, 
    password CHAR(128) NOT NULL,
    salt CHAR(128) NOT NULL,
    email varchar(40) NOT NULL,

    first_name VARCHAR(30) DEFAULT NULL,
    last_name VARCHAR(30) DEFAULT NULL,
    sex ENUM('Male', 'Female') DEFAULT 'Male',
    dob VARCHAR(10) NOT NULL, 
    mobile VARCHAR(12) DEFAULT NULL,

  address VARCHAR(40) DEFAULT NULL,
  address_two VARCHAR(40) DEFAULT NULL,
  city VARCHAR(25) NOT NULL,

    whoami VARCHAR(80) NOT NULL, 
    looking_for ENUM('Short-term','Long-term','Marriage','Dating','Friends/Hang Out','Intimate Encounter','Talk/Email/Pen Pal','Activity Partner') DEFAULT 'Dating',
    ethnicity ENUM('White/Caucasian','Black/African','Hispanic/Latino','Asian','Native American','Middle Eastern','East Indian','Pacific Islander','Mixed Race') DEFAULT NULL,
    marital_status ENUM('Never Married','Divorced','Widowed','Separated','In a Relationship','Not Single/Not Looking') DEFAULT NULL,
    religion ENUM('Atheist','Buddhist/Taoist','Christian/Catholic','Christian/Protestant','Christian/LDS','Christian/Other','Hindu','Jewish','Muslim/Islamic','New Age','Non-religious','Agnostic','Spiritual but not religious','Other Religion') DEFAULT NULL, 
    body_type ENUM('Skinny','Slim/Slender','Fit/Athletic','Toned & Firm','Muscular','Ripped','Modelesque','Average','Proportional','Curvy','Few extra pounds','Full Figured','Stocky','Husky','Voluptuous','Big and Beautiful','Large','Disabled') DEFAULT NULL,
    hair_color ENUM('Auburn','Red','Stawberry Blonde','Platinum Blonde','Blonde','Dark Blonde','Light Brown','Medium Brown','Dark Brown','Black','Radically Dyed','Salt & Pepper','Partial Gray','Gray','Silver/White','Bald/Shaved') DEFAULT NULL,
    drink ENUM('Never','Rarely','Occasionally','Socially','Regularly','Gave it up') DEFAULT NULL,
    smoke ENUM('Never','Socially','Regularly','Trying To Quit') DEFAULT NULL,
    headline VARCHAR(100) DEFAULT NULL, 
    about_user TEXT DEFAULT NULL, 
    ideal_match_info TEXT DEFAULT NULL, 

    last_login TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
    date_registered TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id),
    UNIQUE (email), 
    UNIQUE (username)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我的问题是,我在这个表中使用的ENUM数据类型是否正确。如果这是正确的方式希望任何身体指导我正确的方向。

谢谢。

2 个答案:

答案 0 :(得分:1)

这不是使用ENUM的好方法。您很可能必须更改选项,并且更改ENUM的唯一方法是使用昂贵且容易出错的ALTER TABLE。我会将选项存储为文本(VARCHARTINYTEXT)。从标准化的角度来看,最好为选项创建单独的表,但这会使数据更难理解。

ENUM数据类型最适用于保证选项不变的情况。

答案 1 :(得分:0)

这是使用枚举的一种非常糟糕的方式,因为:

  1. 没有简单的方法可以在网站上添加或删除选项。
  2. 没有简单的方法可以从网站的代码隐藏中获取可能的值列表(比如PHP代码)
  3. 引用枚举值时,在后端代码中出错很容易
  4. 在数据库代码中犯错也很容易。
  5. 用这个来实现i18n并不容易。
  6. 您正在寻找的是一组具有一对多关系的主从表。

    根据您的代码判断,您将获得更多表格:

    looking_for_list (int id, varchar(255) text_en, ... )
    ethnicity_list (int id, varchar(255) text_en, ... )
    marital_status_list (int id, varchar(255) text_en, ... )
    religion_list (int id, varchar(255) text_en, ... )
    body_type_list (int id, varchar(255) text_en, ... )
    hair_color_list (int id, varchar(255) text_en, ... )
    drink_list (int id, varchar(255) text_en, ... )
    smoke_list (int id, varchar(255) text_en, ... )
    

    并通过id(在主表中)引用它们中的值。