Sql 在数据库中存储性别

Sql 在数据库中存储性别,sql,database-design,Sql,Database Design,我希望以尽可能少的(大小/性能)成本将用户的性别存储在数据库中 到目前为止,我想到了3个场景 Int-与代码中的枚举对齐(1=男性,2=女性,3=…) char(1)-存储m、f或另一个单字符标识符 位(布尔)-此选项是否有合适的字段名 我问这个问题的原因是因为它提到字符小于布尔字符 我应该澄清一下,我使用的是MS SQL 2008,它实际上具有位数据类型。选项3是最好的选择,但并非所有DB引擎都具有“位”类型。如果你没有一点,那么TinyINT是你最好的选择 我把这个专栏叫做“性别” 可以排除

我希望以尽可能少的(大小/性能)成本将用户的性别存储在数据库中

到目前为止,我想到了3个场景

  • Int-与代码中的枚举对齐(1=男性,2=女性,3=…)
  • char(1)-存储mf或另一个单字符标识符
  • (布尔)-此选项是否有合适的字段名
  • 我问这个问题的原因是因为它提到字符小于布尔字符


    我应该澄清一下,我使用的是MS SQL 2008,它实际上具有位数据类型。

    选项3是最好的选择,但并非所有DB引擎都具有“位”类型。如果你没有一点,那么TinyINT是你最好的选择

    我把这个专栏叫做“性别”

    可以排除该数据类型,因为它只支持两种可能的性别,这是不够的。虽然支持两个以上的选项,但它需要4个字节——使用更小/更窄的数据类型,性能会更好

    CHAR(1)
    具有优势-两者的字节数相同,但CHAR提供的值的数量更窄。使用
    CHAR(1)
    将使使用“m”、“f”等自然键,而不是使用数字数据(称为代理/人工键)<代码>字符(1)在任何数据库上都受支持,如果需要端口

    结论 我将使用选项2:CHAR(1)

    补遗
    性别列上的索引可能不会有帮助,因为低基数列上的索引没有值。也就是说,指数的值没有足够的多样性来提供任何值。

    医学上有四种性别:男性、女性、不确定和未知。您可能不需要全部四个,但您肯定需要1、2和4。为此数据类型使用默认值是不合适的。更不用说将其视为带有“是”和“不是”状态的布尔值。

    枚举
    字段对齐的
    Int
    (或
    TinyInt
    )将是我的方法

    首先,如果数据库中只有一个
    字段,该行仍将使用一个完整的字节,因此,就节省空间而言,只有当您有多个
    字段时,它才有回报

    其次,字符串/字符对它们来说有一种“神奇的价值”,不管它们在设计时看起来有多明显。更不用说,它让人们存储几乎任何他们不一定映射到任何明显的值


    第三,为了加强引用完整性,数值更容易(也是更好的实践)创建查找表,并且可以与枚举1对1关联,因此在应用程序或数据库的内存中存储数值时存在奇偶校验。

    已经有了ISO标准;无需发明自己的方案:


    根据标准,该列应称为“Sex”,并且“最近的”数据类型应为tinyint,带有检查约束或查找表(视情况而定)

    我使用字符“f”、“m”和“u”,因为我从名字、声音和对话中推测性别,有时不知道性别。最后的决定是他们的意见


    这实际上取决于你对这个人的了解程度,以及你的标准是身体形态还是个人身份。心理学家可能需要更多的选择——异性恋、异性恋、异性恋、异性恋、两性恋和犹豫不决。对于9个选项,不是由单个字符明确定义的,我可能会接受Hugo关于小整数的建议。

    我会选择选项3,但多个不可为空的位列,而不是一个。 IsMale(1=是/0=否) IsFemale(1=是/0=否)

    如有要求: IsUnknownger(1=是/0=否) 等等

    这使得定义易于阅读,易于扩展,易于编程,不可能在域外使用值,也不需要第二个查找表+FK或检查约束来锁定值

    编辑:更正,您至少需要一个约束来确保设置的标志有效

    CREATE TABLE Admission (
        Rno INT PRIMARY KEY AUTO_INCREMENT,
        Name VARCHAR(25) NOT NULL,
        Gender ENUM('M','F'),
        Boolean_Valu boolean,
        Dob Date,
        Fees numeric(7,2) NOT NULL
    );
    
    
    
    
    insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Raj','M',true,'1990-07-12',50000);
    insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Rani','F',false,'1994-05-10',15000);
    select * from admission;
    

    有关于性能的参考吗?我知道这几乎是微观优化,我不应该这样做,但这是我好奇的头脑的食物。谢谢@OMG Ponies,性能怎么样?在这种情况下,一个字符会比一个字符更贵吗?@Marko:就像我之前说的,它们是相等的。但索引可能不会有帮助,因为低基数列上的索引中没有值。也就是说,索引的值没有足够的多样性来提供任何值。如果在64位平台上使用4字节数据类型,性能会有多好?只是说…;-)我会坚持用比特,因为只有两种性别。然而,OP的最初问题仍然是:列名称是什么?“IsMale”或“IsFemale”有点奇怪…@EJP,很有趣。你对此有参考吗?根据这些信息,我会选择与枚举对齐的
    TinyInt
    (如雨果所建议的),并至少选择1、2和3(其他)。@EJP,虽然你的答案可能是正确的,但它没有说我应该使用什么数据类型,而是说-应该使用什么数据类型(技术上)性别是正确的。@Marko:我看不出这句话的意思。您的问题没有问“哪种数据类型”。我的回答排除了你三个建议中的两个,并提供了背景推理。定义了四个值:0=
    未知
    ,1=
    男性
    ,2=
    女性
    ,9=
    未指定
    ,这些值将删除。注意有:性别在注册时(通常在出生后不久)和current.FWIW,所以您提到的问题是指.NET如何在内存中表示这些类型。这与SQLServer如何表示它们无关。bit您使用性别字段的目的是什么?它是否只是一个字符串,以便人们可以输入他们喜欢的内容?尝试
    CREATE TABLE Admission (
        Rno INT PRIMARY KEY AUTO_INCREMENT,
        Name VARCHAR(25) NOT NULL,
        Gender ENUM('M','F'),
        Boolean_Valu boolean,
        Dob Date,
        Fees numeric(7,2) NOT NULL
    );
    
    
    
    
    insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Raj','M',true,'1990-07-12',50000);
    insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Rani','F',false,'1994-05-10',15000);
    select * from admission;