Speichern von Geschlecht in der Datenbank

130

Ich möchte das Geschlecht eines Benutzers in einer Datenbank mit möglichst geringen Kosten (Größe / Leistung) speichern.

Bisher kommen 3 Szenarien in den Sinn

  1. Int - ausgerichtet mit Enum im Code (1 = männlich, 2 = weiblich, 3 = ...)
  2. char (1) - Speichern Sie m , f oder eine andere Einzelzeichen-ID
  3. Bit (Boolescher Wert) - Gibt es einen geeigneten Feldnamen für diese Option?

Der Grund , warum ich frage ist , weil diese Antwort , die erwähnt , dass Zeichen sind kleiner als booleans .

Ich möchte klarstellen, dass ich MS SQL 2008, bin mit der TUT in der Tat die Bitdatentyp haben.

Marko
quelle
1
FWIW, diese SO-Frage, auf die Sie verwiesen haben, bezieht sich darauf, wie .NET diese Typen im Speicher darstellt. Es hat nichts damit zu tun, wie SQL Server sie darstellt. Bit <= char. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt
1
Wofür verwenden Sie das Feld Geschlecht? Könnte es nur eine Zeichenfolge sein, damit die Leute eingeben können, was sie wollen? Der Versuch, alle möglichen Antworten auf diese Frage aufzuzählen, wird schwierig.
Shogged
@ ThePassenger: Ich denke, die übliche Option ist im Grunde m / w / other, also ist ja ternär, wie Sie vorschlagen, in Ordnung. Möglicherweise möchten Sie "andere" von "nicht angegeben" unterscheiden (wie in "Ich sage es nicht" und / oder "Wir haben den Benutzer noch nicht gefragt"). Ich bin mir nicht bewusst, dass geschlechtsspezifische Personen einen Gleitkommawert mit einem Schieberegler wünschen, den sie jeden Tag einstellen können. Ich vermute, dass die meisten von ihnen (und andere nicht traditionell geschlechtsspezifische Personen) gerne auf fast jeder Website "andere" oder "nicht spezifizierte" auswählen würden. Aber nein, ich denke nicht, dass es eine gute Idee wäre, nach "Sex" statt nach "Geschlecht" zu fragen.
Peter Cordes
1
@PeterCordes Mir ist "Gender-Fluid" nicht gut bekannt. In meinem Dorf bist du entweder ein Mann, eine Frau ... oder eine Kuh. Wenn das Genre jetzt fließend ist, scheint es etwas zu viel zu sein, eine Wertskala für den Klang des Computers zu erstellen. In meinem Land fragen wir eher nach dem Sex, es ist weniger kompliziert. Oh, glauben Sie nicht, dass wir uns bisher in der Steinzeit befinden, was? Wir haben Gott bereits entdeckt und sind seit der letzten Kolonialisierung größtenteils Monotheisten.
Revolucion für Monica
2
@PeterCordes: Wenn Sie solche Dinge im aktuellen politischen Klima fordern, erhalten die Menschen Vorteile, indem sie ihnen die Dominanz gegenüber anderen verleihen. Sobald Sie einen Float-Value-Schieberegler einfügen, wird sich jemand melden, der einen mehrdimensionalen fordert. "Nur ein Schieberegler? Bist du in der Steinzeit?"
vsz

Antworten:

82

Ich würde die Spalte "Geschlecht" nennen.

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

Der BIT- Datentyp kann ausgeschlossen werden, da er nur zwei mögliche Geschlechter unterstützt, was nicht ausreichend ist. Während INT mehr als zwei Optionen unterstützt, benötigt es 4 Bytes - die Leistung ist bei einem kleineren / engeren Datentyp besser.

CHAR(1)hat den Vorteil gegenüber TinyINT - beide nehmen die gleiche Anzahl von Bytes an, aber CHAR bietet eine engere Anzahl von Werten. Die Verwendung CHAR(1)würde die Verwendung von "m", "f" usw. zu natürlichen Schlüsseln gegenüber der Verwendung von numerischen Daten machen, die als Ersatz- / künstliche Schlüssel bezeichnet werden. CHAR(1)wird auch in jeder Datenbank unterstützt, falls eine Portierung erforderlich ist.

Fazit

Ich würde Option 2 verwenden: CHAR (1).

Nachtrag

Ein Index in der Spalte "Geschlecht" würde wahrscheinlich nicht helfen, da ein Index in einer Spalte mit niedriger Kardinalität keinen Wert enthält. Das heißt, die Werte sind nicht unterschiedlich genug, damit der Index einen Wert liefert.

OMG Ponys
quelle
Irgendein Hinweis auf die Leistung? Ich weiß, dass es fast eine Mikrooptimierung ist, die ich nicht tun sollte, aber es ist Nahrung für meinen neugierigen Verstand.
Marko
Danke @OMG Ponys, was ist mit der Leistung? Wäre ein Char in diesem Fall am teuersten als ein bisschen?
Marko
4
@ Marko: Wie ich schon sagte, sie sind gleich. Ein Index würde jedoch wahrscheinlich nicht helfen, da ein Index in einer Spalte mit niedriger Kardinalität keinen Wert enthält. Das heißt, die Werte sind nicht unterschiedlich genug, damit der Index einen Wert liefert.
OMG Ponys
1
Wie viel besser wird die Leistung tatsächlich sein, wenn beispielsweise ein 4-Byte-Datentyp auf einer 64-Bit-Plattform verwendet wird? Nur sagen ... ;-)
Craig
1
Ich würde mich an etwas halten, da es nur zwei Geschlechter gibt. Die anfängliche Frage von OP bleibt jedoch: Wie würde der Spaltenname lauten? "IsMale" oder "IsFemale" ist ein wenig seltsam ...
Mateus Felipe
179

Hierfür gibt es bereits einen ISO-Standard. Sie müssen kein eigenes Schema erfinden:

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

Gemäß dem Standard sollte die Spalte "Geschlecht" heißen und der "nächstgelegene" Datentyp wäre tinyint mit einer entsprechenden CHECK-Einschränkung oder Nachschlagetabelle.

Teichleben
quelle
4
Warum springt es für "nicht zutreffend" auf 9? Was ist mit 3-8?
Kenmore
4
Das ist für Sex. OP fragte speziell nach Geschlecht. Geschlecht und Geschlecht haben wahrscheinlich unterschiedliche mögliche Werte, die möglicherweise erfasst werden müssen.
Indigochild
2
@indigochild Das OP verwendet beide Wörter im Fragentitel und betrachtet sie zumindest für seinen Anwendungsfall (YMMV) eindeutig als gleichwertig . Mein Punkt ist einfach, dass es in diesem Bereich einen ISO-Standard gibt und Sie niemals Zeit damit verschwenden sollten, Ihr eigenes Schema zu entwickeln, wenn ein offizieller Standard existiert. Es sei denn natürlich, dieser Standard deckt Ihren speziellen Fall nicht ab, was durchaus möglich ist.
Pondlife
1
Dies sollte die akzeptierte Antwort sein. Es konzentriert sich auf die Datenintegrität (die für immer ist) anstatt auf die Optimierung (die situativ ist).
Paul Cantrell
1
Dies sollte definitiv die Antwort sein. @PeterCordes Diese ISO wird für Sex (biologisches Geschlecht) und nicht für Geschlecht (was Sie identifizieren) verwendet - Erklärung hier . Ich denke, wenn Sie das Geschlecht speichern möchten (was ich nicht wissen würde, welche Verwendung Sie dabei haben), ist ein winziger Int immer noch gut genug, solange Sie weniger als 255 Geschlechter speichern möchten (indem Sie zB 0 sagen = unbekannt / nicht deklarieren wollen, 1 = Mann, 2 = Frau, 3 = Mann identifiziert sich als Frau usw.)
SolidTerre
43

In der Medizin gibt es vier Geschlechter: männlich, weiblich, unbestimmt und unbekannt. Möglicherweise benötigen Sie nicht alle vier, aber sicherlich 1, 2 und 4. Es ist nicht angemessen, einen Standardwert für diesen Datentyp zu haben. Noch weniger, um es als Booleschen Wert mit den Zuständen "ist" und "ist nicht" zu behandeln.

Marquis von Lorne
quelle
1
@EJP, interessant. Haben Sie einen Hinweis darauf?
Marko
11
Mein Vater, MD BS FRACP.
Marquis von Lorne
Basierend auf diesen Informationen würde ich mit TinyInteiner Aufzählung ausgerichtet gehen (wie Hugo vorschlägt) und mit mindestens 1, 2 und 3 (Andere) gehen.
IAbstract
1
@EJP, obwohl Ihre Antwort wahrscheinlich richtig ist, sagt sie NICHT, welchen Datentyp ich verwenden soll, sondern - was die (technisch) richtigen Geschlechter sind.
Marko
17
Das Datenwörterbuch des britischen National Health Service (NHS) definiert vier Werte: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, die die ISO 5218- Werte widerspiegeln . Beachten Sie, dass es zwei Arten gibt : Geschlecht bei der Registrierung (normalerweise kurz nach der Geburt) und aktuell.
Tag, wenn
3

Ein Int(oder TinyInt) an einem EnumFeld ausgerichtet wäre meine Methodik.

Wenn Sie ein einzelnes bitFeld in einer Datenbank haben, verwendet die Zeile weiterhin ein volles Byte. Was die Platzersparnis betrifft, zahlt sich dies nur aus, wenn Sie mehrere bitFelder haben.

Zweitens haben Strings / Zeichen ein "magisches Wertgefühl", unabhängig davon, wie offensichtlich sie zur Entwurfszeit erscheinen mögen. Ganz zu schweigen davon, dass die Benutzer so gut wie jeden Wert speichern können, den sie nicht unbedingt auf etwas Offensichtliches abbilden würden.

Drittens ist es viel einfacher (und besser), eine Nachschlagetabelle für einen numerischen Wert zu erstellen, um die referenzielle Integrität zu erzwingen, und er kann 1: 1 mit einer Aufzählung korrelieren, sodass die Speicherung des Werts im Speicher paritätisch ist die Anwendung oder in der Datenbank.

Hugo
quelle
2

Ich benutze char 'f', 'm' und 'u', weil ich das Geschlecht anhand von Name, Stimme und Konversation vermute und manchmal das Geschlecht nicht kenne. Die endgültige Entscheidung ist ihre Meinung.

Es hängt wirklich davon ab, wie gut Sie die Person kennen und ob Ihre Kriterien die physische Form oder die persönliche Identität sind. Ein Psychologe benötigt möglicherweise zusätzliche Optionen - Kreuz zu Frau, Kreuz zu Mann, Trans zu Frau, Trans zu Mann, Zwitter und Unentschlossen. Mit 9 Optionen, die nicht durch ein einzelnes Zeichen klar definiert sind, könnte ich Hugos Ratschlag einer winzigen ganzen Zahl befolgen.

Zarac
quelle
Nicht zum Thema. Es ist keine Antwort.
Hod
1

Option 3 ist die beste Wahl, aber nicht alle DB-Engines haben einen "Bit" -Typ. Wenn Sie kein bisschen Zeit haben, ist TinyINT die beste Wahl.

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

Geben Sie hier die Linkbeschreibung ein

Mohammad Asif
quelle
-5

Ich würde mit Option 3 gehen, aber mehrere NON NULLABLE-Bitspalten anstelle von einer. IsMale (1 = Ja / 0 = Nein) IsFemale (1 = Ja / 0 = Nein)

falls erforderlich: IsUnknownGender (1 = Ja / 0 = Nein) und so weiter ...

Dies ermöglicht ein einfaches Lesen der Definitionen, eine einfache Erweiterbarkeit, eine einfache Programmierbarkeit, keine Möglichkeit, Werte außerhalb der Domäne zu verwenden, und keine Notwendigkeit einer zweiten Nachschlagetabelle + FK- oder CHECK-Einschränkungen zum Sperren der Werte.

BEARBEITEN: Korrektur, Sie benötigen mindestens eine Einschränkung, um sicherzustellen, dass die gesetzten Flags gültig sind.

HansLindgren
quelle
Es wäre schön zu hören, warum meine Antwort abgelehnt wird.
HansLindgren
Ohne Einschränkungen hindert nichts daran, dass alle Spalten 1 oder alle 0 sind. Dies wäre unsinnig, sodass Ihr Schema keinen Ihrer Ansprüche erfüllt.
Jay Kominek
Ja, Sie haben Recht, dass Sie eine Einschränkung benötigen, um zu überprüfen, ob die richtige Anzahl von Flags aktiviert ist. Ich denke jedoch nicht, dass alle Abstimmungen für diese Unterlassung sind ...
HansLindgren
Es ist eine häufig besuchte Frage (siehe die Upvotes für einige der anderen Antworten!), Und Sie kamen Jahre später und fügten eine Antwort hinzu, die einer One-Hot-Codierung gleichkommt, einer weit verbreiteten Technik, die nicht einmal die hat wenige konkrete Eigenschaften, die Sie ihm zuschreiben. Ich denke nicht, dass es richtig war, Sie unter 0 zu stimmen, aber ich bin auch nicht überrascht, dass es passiert ist.
Jay Kominek