Veritabanında cinsiyet (cinsiyet) depolamak


130

Mümkün olduğunca az (boyut / performans) maliyetle bir veritabanında bir kullanıcının cinsiyetini depolamak istiyorum.

Şimdiye kadar akla 3 senaryo geliyor

  1. Int - kodda Enum ile hizalı (1 = Erkek, 2 = Kadın, 3 = ...)
  2. kömür (1) - deposu m , f ya da başka tek bir karakter tanımlayıcı
  3. Bit (boolean) - bu seçenek için uygun bir alan adı var mı?

Bunu sormamın sebebi bu nedenle olduğunu cevap bahseder karakter olan daha küçük daha Boolean .

Ben MS SQL 2008 kullanıyorum olduğunu açıklamak gerekir YAPAR bit veri türü var aslında.


1
FWIW, başvurduğunuz SO sorusu, .NET'in bellekte bu türleri nasıl temsil ettiğiyle ilgilidir. SQL Server'ın onları nasıl temsil ettiğiyle ilgisi yok. bit <= karakter. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt

1
Cinsiyet alanını ne için kullanıyorsunuz? İnsanların istediklerini girebilmesi için bu sadece bir dizi olabilir mi? Bu soruya verilebilecek tüm olası yanıtları sıralamaya çalışmak zor olacaktır.
2018

@ ThePassenger: Bence her zamanki seçenek temelde m / f / diğer, yani evet önerdiğiniz gibi üçlü iyi. "Diğer" i "belirtilmemiş" den ayırt etmek isteyebilirsiniz ("söylemiyorum" ve / veya "kullanıcıya henüz sormadık" gibi). Cinsiyet açısından akışkan insanların her gün ayarlayabilecekleri bir kaydırıcıyla bir kayan nokta değeri istediklerini bilmiyorum; Benim tahminim, çoğu (ve geleneksel olarak cinsiyete sahip olmayan diğer insanlar) hemen hemen her web sitesinde "diğer" veya "belirtilmemiş" seçeneğini seçmekten mutlu olacaklardır. Ama hayır, "cinsiyet" yerine "seks" istemenin iyi bir fikir olacağını sanmıyorum.
Peter Cordes

1
@PeterCordes "Cinsiyet akışkanlığı" ndan pek haberdar değilim, benim köyümde ya bir erkek, bir kadın ... ya da bir inek. Tür artık akıcıysa, bilgisayarın sesi için bir değer ölçeği yaratmak biraz fazla sorulacak gibi görünüyor. Benim ülkemde seks istemeyi tercih ediyoruz, bu daha az karmaşık. Oh, şimdiye kadar Taş Devri'nde olduğumuza inanmayın, eh! Tanrı'yı ​​zaten keşfettik ve son sömürgeleştirmeden bu yana çoğunlukla tektanrıcıyız.
Revolucion for Monica

2
@PeterCordes: Mevcut siyasi ortamda bu tür şeyleri talep etmek, insanlara başkalarına üstünlük sağlayarak avantajlar sağlayacağından, bir kayan değer kaydırıcısı eklediğinizde, birisi çok boyutlu bir kayar nokta talep edecek. "Sadece bir kaydırıcı mı? Taş devrinde misiniz?"
vsz

Yanıtlar:


83

Sütuna "cinsiyet" adını verirdim.

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 sadece yetersizdir iki olası cinsiyetler destekler çünkü veri tipi ekarte edilebilir. İken INT destekleri ikiden fazla seçenek, bu 4 bayt alır - performans daha küçük / daha dar veri türüyle iyi olacaktır.

CHAR(1) üstünlüğe sahip TinyINT - her ikisi de aynı sayıda bayt alır, ancak CHAR daha dar sayıda değer sağlar. Kullanmak CHAR(1)"m", "f", vb. Doğal anahtarların yerine vekil / yapay anahtarlar olarak adlandırılan sayısal verilerin kullanılmasını sağlar. CHAR(1)ayrıca herhangi bir veri tabanında da desteklenir, eğer bir porta ihtiyaç duyulursa.

Sonuç

Seçenek 2'yi kullanırdım: CHAR (1).

ek

Cinsiyet sütun üzerinde bir dizin muhtemelen olurdu değil düşük kardinalite sütun üzerinde bir dizin içinde hiçbir değeri yok, çünkü yardımcı olur. Yani, dizinin herhangi bir değer sağlaması için değerlerde yeterli çeşitlilik yok.


Performansla ilgili herhangi bir referans var mı? Yapmamam gereken neredeyse mikro optimizasyon olduğunu biliyorum, ama meraklı zihnim için yiyecek.
Marko

Teşekkürler @OMG Ponies, peki ya performans? Bu durumda bir kömür biraz daha mı maliyetli olur?
Marko

4
@Marko: Daha önce de söylediğim gibi, eşitler. Ama bir dizin olasılıkla olurdu değil düşük kardinalite sütun üzerinde bir dizin içinde hiçbir değeri yok, çünkü yardımcı olur. Yani, dizinin herhangi bir değer sağlaması için değerlerde yeterli çeşitlilik yok.
OMG Ponies

1
64 bitlik bir platformda, örneğin 4 baytlık bir veri türünü kullanan performans gerçekten ne kadar iyi olacak? Sadece söylüyorum ... ;-)
Craig

1
Sadece iki cinsiyet olduğu için biraz takılırdım. Bununla birlikte, OP'nin ilk sorusu kalır: sütun adı ne olurdu? "IsMale" veya "IsFemale" biraz garip ...
Mateus Felipe

180

Bunun için zaten bir ISO standardı var; kendi planınızı icat etmenize gerek yok:

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

Standarda göre, sütun "Cinsiyet" olarak adlandırılmalı ve "en yakın" veri türü, uygun şekilde bir KONTROL kısıtlaması veya arama tablosu içeren çok küçük olmalıdır.


4
Neden 'uygun değil' için 9'a atlıyor? 3-8 ne olacak?
Kenmore

4
Bu seks için. OP özellikle cinsiyet sordu. Cinsiyet ve cinsiyet muhtemelen ele geçirilmesi gerekebilecek farklı olası değerlere sahiptir.
indigochild

2
@indigochild OP, soru başlığında her iki kelimeyi de kullanır ve en azından kendi kullanım durumu (YMMV) için bunların eşdeğer olduklarını açıkça kabul eder . Demek istediğim basitçe, bu alanda bir ISO standardı var ve resmi bir standart varken asla kendi planınızı oluşturmak için zaman harcamamalısınız. Tabii ki bu standart sizin durumunuzu kapsamadığı sürece, ki bu tamamen mümkündür.
Pondlife

1
Kabul edilen cevap bu olmalıdır. Optimizasyon (durumsal) yerine veri bütünlüğüne (sonsuza dek) odaklanır.
Paul Cantrell

1
Cevap kesinlikle bu olmalı. @PeterCordes, bu ISO Cinsiyet (biyolojik cinsiyet) için kullanılır, Cinsiyet (sizin tanımladığınız şey) için kullanılır - açıklama burada . Sanırım cinsiyeti saklamak istemeniz durumunda (ki bunu hangi amaçla yaptığınızı bilmiyorum), 255 cinsiyetten daha azını saklamak istediğiniz sürece küçük bir int hala yeterince iyidir (fe 0 diyerek = bilinmiyor / beyan etmek istemiyor, 1 = erkek, 2 = kadın, 3 = kadın olarak tanımlayan erkek, vb.)
SolidTerre

43

Tıpta dört cinsiyet vardır: erkek, kadın, belirsiz ve bilinmeyen. Dördüne de ihtiyacınız olmayabilir, ancak kesinlikle 1, 2 ve 4'e ihtiyacınız vardır. Bu veri türü için varsayılan bir değere sahip olmak uygun değildir. Buna 'eşittir' ve 'değil' durumlarına sahip bir Boole olarak ele almak daha da az.


1
@EJP, ilginç. Buna bir referansınız var mı?
Marko

11
Babam, MD BS FRACP.
Marquis of Lorne

Bu bilgilere dayanarak, TinyInt(Hugo'nun önerdiği gibi) bir numaralandırma ile uyumlu hale gelir ve en az 1, 2 ve 3 (Diğer) ile giderdim.
IAbstract

1
@EJP, cevabınız muhtemelen doğru olsa da, hangi veri tipini kullanmam gerektiğini söylemiyor, bunun yerine - (teknik olarak) doğru cinsiyetlerin ne olduğunu söylüyor.
Marko

17
İngiltere Ulusal Sağlık Servisi (NHS) veri sözlüğü dört değer tanımlar: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, bu ISO 5218 değerlerini yansıtır . İki tür olduğunu unutmayın : kayıt sırasında cinsiyet (genellikle doğumdan kısa bir süre sonra) ve şimdiki.
onedaywhen

3

Bir alana hizalanmış Int(veya TinyInt) Enumbenim metodolojim olacaktır.

İlk olarak, bitbir veritabanında tek bir alanınız varsa , satır yine de tam bayt kullanacaktır, bu nedenle alan tasarrufu açısından, yalnızca birden fazla alanınız varsa işe yarar bit.

İkincisi, dizgelerin / karakterlerin, tasarım zamanında ne kadar açık görünürlerse görünsünler onlara "sihirli bir değeri" hissi verir. Bahsetmiyorum bile, insanların bariz herhangi bir şeyle eşleştirmeyecekleri hemen hemen her değeri depolamasına izin veriyor.

Üçüncüsü, sayısal bir değer, bilgi tutarlılığını güçlendirmek için bir arama tablosu oluşturmak çok daha kolaydır (ve daha iyi bir uygulamadır) ve bir enum ile 1'e 1 arasında ilişki kurabilir, bu nedenle değerin bellekte depolanmasında eşitlik vardır. uygulama veya veri tabanında.


2

Karakter 'f', 'm' ve 'u' kullanıyorum çünkü cinsiyeti isimden, sesten ve konuşmadan tahmin ediyorum ve bazen cinsiyeti bilmiyorum. Nihai karar onların fikirleri.

Bu gerçekten kişiyi ne kadar iyi tanıdığınıza ve kriterlerinizin fiziksel form mu yoksa kişisel kimlik mi olduğuna bağlıdır. Bir psikolog ek seçeneklere ihtiyaç duyabilir - kadına çapraz, erkeğe çapraz, dişiye trans, erkeğe trans, hermafrodit ve kararsız. Tek bir karakterle açıkça tanımlanmayan 9 seçenekle, Hugo'nun minik tamsayı tavsiyesiyle gidebilirim.


Konuyla ilgili değil. Bu bir cevap değil.
hod

1

Seçenek 3 en iyi seçeneğinizdir, ancak tüm DB motorlarının "bit" tipi yoktur. Biraz sahip değilseniz, TinyINT en iyi bahsiniz olacaktır.


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

bağlantı açıklamasını buraya girin


-5

Seçenek 3 ile giderdim, ancak bir yerine birden çok NON NULLABLE bit sütunu. IsMale (1 = Evet / 0 = Hayır) IsFemale (1 = Evet / 0 = Hayır)

istenirse: IsUnknownGender (1 = Yes / 0 = No) ve benzeri ...

Bu, tanımların kolay okunmasını, kolay genişletilebilirliği, kolay programlanabilirliği, etki alanı dışındaki değerleri kullanma olasılığını ortadan kaldırır ve değerleri kilitlemek için ikinci bir arama tablosu + FK veya KONTROL kısıtlamalarına gerek yoktur.

DÜZENLEME: Düzeltme, ayarlanan bayrakların geçerli olmasını sağlamak için en az bir kısıtlamaya ihtiyacınız var.


Cevabımın neden reddedildiğini duymak güzel olurdu?
HansLindgren

Kısıtlamalar olmadan hiçbir şey tüm sütunların 1 olmasını veya hepsinin 0 olmasını engelleyemez. Bu mantıksız olurdu, bu yüzden planınız iddialarınızdan birini karşılamıyor.
Jay Kominek

Evet, doğru bayrak sayısının 'kontrol edildiğini' kontrol etmek için bir kısıtlamaya ihtiyacınız olduğu konusunda haklısınız. Tüm
olumsuz oyların

Bu yoğun bir şekilde ziyaret edilen bir sorudur (diğer cevapların bazılarının olumlu oylarına bakın!) Ve yıllar sonra gelip tek sıcak kodlamaya varan bir cevap eklediniz, yaygın olarak öğretilen bir teknik, ona atfettiğin birkaç somut özellik. 0'ın altında oy vermenin doğru olduğunu sanmıyorum, ama buna da şaşırmadım.
Jay Kominek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.