Przechowywanie płci w bazie danych


134

Chcę przechowywać płeć użytkownika w bazie danych przy jak najmniejszych kosztach (rozmiar / wydajność).

Jak dotąd przychodzą na myśl 3 scenariusze

  1. Int - wyrównane z wyliczeniem w kodzie (1 = mężczyzna, 2 = kobieta, 3 = ...)
  2. char (1) - Przechowuj m , f lub inny pojedynczy identyfikator znaku
  3. Bit (boolean) - czy istnieje odpowiednia nazwa pola dla tej opcji?

Powodem, o który pytam, jest ta odpowiedź, która wspomina, że znakimniejsze niż wartości logiczne .

Należy wyjaśnić, że używam MS SQL 2008, który robi w rzeczywistości mają bitowego typu danych.


1
FWIW, to pytanie SO, do którego się odwołałeś, dotyczy tego, jak .NET reprezentuje te typy w pamięci. Nie ma to nic wspólnego z tym, jak przedstawia je SQL Server. bit <= znak. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt

1
Do czego używasz pola płci? Czy może to być po prostu ciąg znaków, aby ludzie mogli wprowadzić to, co im się podoba? Próba wyliczenia wszystkich możliwych odpowiedzi na to pytanie będzie trudna.
shogged

@ThePassenger: Myślę, że zwykłą opcją jest w zasadzie m / f / other, więc tak, trójskładnikowy, jak sugerujesz, jest w porządku. Możesz odróżnić „inny” od „nieokreślony” (np. „Nie mówię” i / lub „jeszcze nie zapytaliśmy użytkownika”). Nie znam ludzi, którzy mają zmienną płeć i chcą mieć wartość zmiennoprzecinkową z suwakiem, który mogą ustawiać każdego dnia; przypuszczam, że większość z nich (i inne osoby o nietradycyjnej płci) z przyjemnością wybrałaby po prostu „inne” lub „nieokreślone” w prawie każdej witrynie. Ale nie, nie sądzę, żeby pytanie o „seks” zamiast „płeć” było dobrym pomysłem.
Peter Cordes

1
@PeterCordes Nie jestem świadomy „płynu płciowego”, w mojej wiosce jest albo mężczyzna, kobieta ... albo krowa. Jeśli gatunek jest teraz płynny, tworzenie skali wartości, jeśli chodzi o dźwięk komputera, wydaje się zbyt trudne. W moim kraju raczej prosimy o seks, jest to mniej skomplikowane. Och, nie wierzcie, że do tej pory jesteśmy w epoce kamiennej, eh! Odkryliśmy już Boga i od czasu ostatniej kolonizacji jesteśmy w większości monoteistami.
Revolucion dla Moniki

2
@PeterCordes: ponieważ wymaganie takich rzeczy w obecnym klimacie politycznym da ludziom korzyści, zapewniając im dominację nad innymi, jak tylko dodasz suwak wartości zmiennoprzecinkowej, ktoś wystąpi z żądaniem wielowymiarowego. "Tylko jeden suwak? Czy jesteś w epoce kamiennej?"
vsz

Odpowiedzi:


84

Nazwałbym kolumnę „płcią”.

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 typ danych można wykluczyć, ponieważ obsługuje tylko dwie płcie, które możliwe jest niewystarczająca. Podczas gdy INT obsługuje więcej niż dwie opcje, zajmuje 4 bajty - wydajność będzie lepsza przy mniejszym / węższym typie danych.

CHAR(1)ma przewagę nad TinyINT - oba zajmują tę samą liczbę bajtów, ale CHAR zapewnia węższą liczbę wartości. Użycie CHAR(1)spowodowałoby użycie naturalnych kluczy "m", "f" itp., Zamiast użycia danych numerycznych, które są określane jako klucze zastępcze / sztuczne. CHAR(1)jest również obsługiwany w każdej bazie danych, jeśli zajdzie potrzeba przeniesienia.

Wniosek

Użyłbym opcji 2: CHAR (1).

Uzupełnienie

Indeks w kolumnie płci prawdopodobnie nie pomógłby, ponieważ w indeksie w kolumnie o niskiej liczności nie ma wartości. Oznacza to, że nie ma wystarczającej różnorodności wartości, aby indeks mógł podać jakąkolwiek wartość.


Jakieś odniesienie do wydajności? Wiem, że to prawie mikro-optymalizacja, której nie powinienem robić, ale to pożywka dla mojego ciekawskiego umysłu.
Marko

Dzięki @OMG Kucyki, a co z wydajnością? Czy w tym przypadku char byłby bardziej kosztowny niż trochę?
Marko

4
@Marko: Jak powiedziałem wcześniej, są równe. Ale indeks prawdopodobnie nie pomógłby, ponieważ w indeksie nie ma wartości w kolumnie o niskiej liczności. Oznacza to, że nie ma wystarczającej różnorodności wartości, aby indeks mógł podać jakąkolwiek wartość.
OMG Kucyki

1
O ileż lepiej jest wydajność naprawdę zamiar używać, powiedzmy, typ danych 4 bajtów na platformie 64-bitowej? Tylko mówię ... ;-)
Craig

1
Trzymałbym się nieco, ponieważ są tylko dwie płci. Jednak początkowe pytanie OP pozostaje: jaka byłaby nazwa kolumny? „IsMale” lub „IsFemale” jest trochę dziwne ...
Mateus Felipe

183

Istnieje już norma ISO w tym zakresie; nie musisz wymyślać własnego schematu:

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

Zgodnie ze standardem kolumna powinna nosić nazwę „Płeć”, a „najbliższy” typ danych to tinyint z ograniczeniem CHECK lub odpowiednio z tabelą przeglądową.


4
Dlaczego przeskakuje do 9 dla „nie dotyczy”? A co z 3-8?
Kenmore

4
To jest dla seksu. OP specjalnie zapytał o płeć. Płeć i płeć prawdopodobnie mają różne możliwe wartości, które mogą wymagać uchwycenia.
indigochild

3
@indigochild OP używa obu słów w tytule pytania i wyraźnie uważa je za równoważne, przynajmniej w swoim przypadku użycia (YMMV). Chodzi mi po prostu o to, że w tej dziedzinie istnieje norma ISO i nigdy nie powinieneś tracić czasu na opracowywanie własnego schematu, jeśli istnieje oficjalna norma. Chyba że, oczywiście, ten standard nie obejmuje twojego konkretnego przypadku, co jest całkowicie możliwe.
Pondlife,

1
To powinna być akceptowana odpowiedź. Koncentruje się na integralności danych (która jest ~ na zawsze) zamiast optymalizacji (która jest sytuacyjna).
Paul Cantrell

1
To zdecydowanie powinna być odpowiedź. @PeterCordes to ISO jest używane w odniesieniu do płci (płci biologicznej), a nie płci (tego, co określasz jako) - wyjaśnienie tutaj . Wydaje mi się, że w przypadku chęci przechowywania płci (której, nie wiedziałbym, do jakiego zastosowania to robisz), mała liczba int jest nadal wystarczająco dobra, o ile chcesz przechowywać mniej niż 255 płci (mówiąc np. 0 = nieznany / nie chcący deklarować, 1 = mężczyzna, 2 = kobieta, 3 = mężczyzna identyfikujący się jako kobieta itp.)
SolidTerre

43

W medycynie wyróżnia się cztery płci: męską, żeńską, nieokreśloną i nieznaną. Możesz nie potrzebować wszystkich czterech, ale z pewnością potrzebujesz 1, 2 i 4. Nie jest właściwe posiadanie wartości domyślnej dla tego typu danych. Jeszcze mniej traktować go jako wartość logiczną ze stanami „jest” i „nie jest”.


1
@EJP, ciekawe. Czy masz do tego odniesienie?
Marko

11
Mój ojciec, MD BS FRACP.
Markiz Lorne

Na podstawie tych informacji TinyIntwybrałbym wyrównanie z wyliczeniem (jak sugeruje Hugo) i wybrałbym co najmniej 1, 2 i 3 (inne).
IAbstract

1
@EJP, chociaż twoja odpowiedź prawdopodobnie jest poprawna, NIE mówi, jakiego typu danych powinienem użyć, ale raczej - jakie (technicznie) są poprawne rodzaje.
Marko

19
Słownik danych brytyjskiej National Health Service (NHS) definiuje cztery wartości: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, które odzwierciedlają wartości ISO 5218 . Uwaga: istnieją dwa rodzaje : płeć w momencie rejestracji (zwykle krótko po urodzeniu) i aktualna.
kiedy

3

Int(Lub TinyInt) dostosowane do Enumpola byłaby moja metodologia.

Po pierwsze, jeśli masz jedno bitpole w bazie danych, wiersz nadal będzie używał pełnego bajtu, więc jeśli chodzi o oszczędność miejsca, opłaca się tylko wtedy, gdy masz wiele bitpól.

Po drugie, łańcuchy / znaki mają "magiczną wartość", niezależnie od tego, jak oczywiste mogą się wydawać w czasie projektowania. Nie wspominając już o tym, że pozwala ludziom przechowywać dowolną wartość, której niekoniecznie odwzorowaliby na coś oczywistego.

Po trzecie, wartość liczbowa jest znacznie łatwiejsza (i lepsza praktyka), aby utworzyć tabelę przeglądową, aby wymusić integralność referencyjną i może korelować 1 do 1 z wyliczeniem, więc istnieje parzystość w przechowywaniu wartości w pamięci w w aplikacji lub w bazie danych.


2

Używam znaków „f”, „m” i „u”, ponieważ przypuszczam płeć na podstawie imienia, głosu i rozmowy, a czasami nie znam płci. Ostateczna decyzja jest ich zdaniem.

To naprawdę zależy od tego, jak dobrze znasz osobę i od tego, czy twoje kryteria to forma fizyczna czy tożsamość osobista. Psycholog może potrzebować dodatkowych opcji - skrzyżowanie z kobietą, skrzyżowanie z mężczyzną, trans z kobietą, trans z mężczyzną, hermafrodyta i niezdecydowani. Mając 9 opcji, które nie są jasno zdefiniowane przez jeden znak, mogę skorzystać z rady Hugo dotyczącej małej liczby całkowitej.


Nie na temat. To nie jest odpowiedź.
hod

1

Opcja 3 jest najlepszym rozwiązaniem, ale nie wszystkie silniki DB mają typ „bitowy”. Jeśli nie masz trochę, najlepszym rozwiązaniem będzie 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;

wprowadź opis linku tutaj


-6

Wybrałbym opcję 3, ale wiele kolumn bitowych NON NULLABLE zamiast jednej. IsMale (1 = Tak / 0 = Nie) IsFemale (1 = Tak / 0 = Nie)

jeśli wymagane: IsUnknownGender (1 = Tak / 0 = Nie) i tak dalej ...

Ułatwia to czytanie definicji, łatwą rozszerzalność, łatwą programowalność, brak możliwości użycia wartości spoza domeny i brak wymogu stosowania drugiej tabeli przeglądowej + ograniczeń FK lub CHECK w celu zablokowania wartości.

EDYCJA: Korekta, potrzebujesz co najmniej jednego ograniczenia, aby upewnić się, że ustawione flagi są prawidłowe.


Byłoby miło usłyszeć, dlaczego moja odpowiedź została odrzucona?
HansLindgren

Bez ograniczeń nic nie stoi na przeszkodzie, aby wszystkie kolumny były równe 1 lub wszystkie z nich były równe zeru, co byłoby bezsensowne, więc Twój schemat nie spełnia jednego z Twoich twierdzeń.
Jay Kominek

Tak, masz rację, że potrzebujesz jednego ograniczenia, aby sprawdzić, czy poprawna liczba flag jest „zaznaczona”. Nie sądzę jednak, aby wszystkie głosy przeciwne były za tym pominięciem ...
HansLindgren

Jest to często odwiedzane pytanie (spójrz na głosy poparcia dla niektórych innych odpowiedzi!), A Ty przyszedłeś po latach i dodałeś odpowiedź, która sprowadza się do kodowania na gorąco, szeroko nauczanej techniki, która nawet nie ma kilka konkretnych właściwości, które mu przypisujesz. Nie sądzę, aby głosowanie na Ciebie poniżej 0 było słuszne, ale też nie dziwię się, że tak się stało.
Jay Kominek
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.