在数据库中存储性别(性别)


130

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

到目前为止,我想到了3种情况

  1. INT - 在代码与枚举对齐(1 =男,2 =女性,3 = ...)
  2. char(1) - 存储mf或另一个单个字符标识符
  3. (布尔值) - 此选项是否有适当的字段名称?

我想问的原因是因为这个的答案,其提到字符布尔值

我要澄清,我使用MS SQL 2008,它DOES其实有位数据类型。


1
FWIW,您提到的SO问题是指.NET如何在内存中表示这些类型。它与SQL Server表示它们的方式没有任何关系。位<=字符。 msdn.microsoft.com/en-us/library/ms177603.aspx
Matt

1
您将性别字段用于什么?可以只是一个字符串,以便人们输入自己喜欢的东西吗?试图枚举对该问题的所有可能答案将非常棘手。
shogged

@ThePassenger:我认为通常的选择基本上是m / f / other,所以像您建议的那样,三元是好的。您可能要区分“其他”和“未指定”(如“我不告诉”和/或“我们还没有询问用户”)。我不知道对性别敏感的人想要一个每天都可以设置的带有浮点的浮点值;我的猜测是,大多数人(以及其他非传统性别的人)很乐意在几乎任何网站上选择“其他”或“未指定”。但是,不,我认为要求“性别”而不是“性别”不是一个好主意。
彼得·科德斯

1
@PeterCordes我不太了解“性别流”,在我们村子里,您是男人,女人...还是母牛。如果现在这种类型是不固定的,那么就计算机的声音而言,创建一个价值标尺似乎有点不容易提出。在我国,我们宁愿要求做爱,也没有那么复杂。哦,不要相信我们目前处在石器时代,!自上次殖民以来,我们已经发现了上帝,并且在大多数情况下我们都是一神教徒。
Monica的革命,

2
@PeterCordes:由于在当前的政治环境中要求这种事情将通过使其在他人中占主导地位而给人们带来好处,因此,一旦您包括了浮动价值滑块,就会有人提出要求多维的东西。“只有一个滑块?您处在石器时代吗?”
vsz

Answers:


82

我称该列为“性别”。

Data Type   Bytes Taken          Number/Range of Values
------------------------------------------------
TinyINT     1                    255 (zero to 255)
INT         4            -       2,147,483,648 to 2,147,483,647
BIT         1 (2 if 9+ columns)  2 (0 and 1)
CHAR(1)     1                    26 if case insensitive, 52 otherwise

BIT数据类型可以排除,因为它仅支持两种可能的性别是不够的。当INT支持两个以上的选项,但它占用4个字节-使用更小/更窄的数据类型,性能会更好。

CHAR(1)TinyINT上有优势-两者占用相同数量的字节,但是CHAR提供了更窄的值数量。使用CHAR(1)将使用“ m”,“ f”等自然键,而不是使用被称为替代/人工键的数字数据。 CHAR(1)如果需要移植,任何数据库也都支持。

结论

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

附录

在性别列的索引很可能将不会帮助,因为有一个在一个低基数列的索引没有价值。意思是,索引值的多样性不足以提供任何值。


对性能有何提及?我知道这几乎是微优化,我不应该这样做,但这是我好奇的头脑的食物。
Marko 2010年

感谢@OMG Ponies,性能如何?在这种情况下,char会比一点花费最大吗?
Marko

4
@Marko:就像我之前说的,它们是平等的。但指数可能将不会帮助,因为有一个在一个低基数列的索引没有价值。意思是,索引值的多样性不足以提供任何值。
OMG小马

1
例如,在64位平台上使用4字节数据类型,性能真的要好多少?只是说... ;-)
克雷格

1
我会坚持一点,因为只有两种性别。但是,OP最初的问题仍然是:列名是什么?“ IsMale”或“ IsFemale”有点奇怪...
Mateus Felipe

180

为此已经有一个ISO标准。无需发明自己的方案:

http://en.wikipedia.org/wiki/ISO_5218

按照标准,该列应称为“ Sex”,并且“最接近”的数据类型将是tinyint,并带有适当的CHECK约束或查找表。


4
为什么将“不适用”跳到9?3-8呢?
Kenmore

4
这是为了性。OP专门要求性别。性别和性别可能具有不同的可能价值,可能需要捕获这些价值。
indigochild

2
@indigochild OP在问题标题中使用了两个单词,并且至少在他的用例(YMMV)中清楚地认为它们是等效的。我的观点很简单,那就是在这一领域存在ISO标准,当存在正式标准时,您永远不应浪费时间来设计自己的方案。当然,除非该标准不涵盖您的特殊情况,否则这完全有可能。
Pondlife,2015年

1
这应该是公认的答案。它专注于数据完整性(这是永远的)而不是优化(这是情境)。
Paul Cantrell

1
绝对应该是答案。@PeterCordes,此ISO用于性别(生物性别)而不是性别(您标识为)- 在此进行解释。我想在要存储性别的情况下(我不知道您使用了哪种方法),只要您要存储少于255个性别(只要说出fe 0),一个小整数就足够了。 =未知/不想声明,1 =男人,2 =女人,3 =标识为女人的男人,
依此类推

43

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


1
@EJP,有趣。您对此有参考吗?
Marko,2010年

11
我的父亲,医学博士BS FRACP。
罗恩侯爵

根据此信息,我将与TinyInt枚举(如Hugo所建议的)对齐,并至少与1、2和3(其他)一起使用。
IAbstract

1
@EJP,尽管您的答案可能是正确的,但它并未说明我应使用哪种数据类型,而是-(技术上正确的)性别是什么。
Marko 2010年

17
英国国家卫生局(NHS)数据字典定义了四个值:0 = Not Known,1 = Male,2 = Female,9 = Not Specified,这与ISO 5218值相同。注意有两种类型:注册时的性别(通常是出生后不久)和当前的性别。
一天,2012年

3

Int(或TinyInt)对齐Enum字段将是我的方法。

首先,如果您bit在数据库中只有一个字段,那么该行仍将使用一个完整的字节,因此就节省空间而言,只有在您拥有多个字段的情况下,该行才能奏效bit字段的情况下。

其次,字符串/字符对它们具有“魔幻值”的感觉,无论它们在设计时看起来多么明显。更不用说,它使人们可以存储几乎不必映射到任何显而易见的值的任何值。

第三,数值更容易(更好的做法)为其创建查找表,以增强参照完整性,并且可以将1对1与枚举相关联,因此在将值存储在内存中时存在奇偶校验应用程序或数据库中。


2

我使用char'f','m'和'u'是因为我从名字,声音和谈话中推测性别,有时甚至不知道性别。最终决定是他们的意见。

这实际上取决于您对人的了解程度以及您的标准是身体形态还是个人身份。心理学家可能需要其他选择-与女性交配,与男性交配,与女性交配,与男性交配,雌雄同体且未定。对于9个选项(单个字符未明确定义),我可能会接受Hugo的小整数建议。


没有话题。这不是答案。
HOD

1

选项3是最好的选择,但是并非所有的数据库引擎都具有“位”类型。如果您没空,TinyINT将是您最好的选择。


-5
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;

在此处输入链接说明


-5

我会选择3,但要使用多个NON NULLABLE位列而不是一个。IsMale(1 =是/ 0 =否)Ismale(1 =是/ 0 =否)

如果需要:IsUnknownGender(1 =是/ 0 =否),依此类推...

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

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


很高兴听到我的答案为什么被否决?
HansLindgren

没有约束,没有什么可以阻止所有列都为1或所有列都为0。这将是毫无意义的,因此您的方案无法满足您的要求之一。
Jay Kominek

是的,您是对的,您确实需要一个约束来检查是否“检查”了正确数量的标志。我不认为所有反对的理由都是这样。
汉斯·林格伦

这是一个访问量很大的问题(请查看其他答案的投票!),几年之后,您又添加了一个答案,相当于一个热编码,这是一种广为传授的技术,甚至没有您归因于它的一些具体属性。我认为将您的票选在0以下是不正确的,但我也不感到惊讶。
杰伊·科米尼克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.