Memorizzazione del sesso (genere) nel database


130

Voglio archiviare il genere di un utente in un database con il minor costo (dimensioni / prestazioni) possibile.

Finora, mi vengono in mente 3 scenari

  1. Int - allineato con Enum nel codice (1 = Maschio, 2 = Femmina, 3 = ...)
  2. char (1) - Memorizza m , f o un altro identificatore a carattere singolo
  3. Bit (booleano) : esiste un nome campo appropriato per questa opzione?

Il motivo per cui chiedo è a causa di questa risposta che menziona che i caratteri sono più piccoli dei booleani .

Vorrei chiarire che sto utilizzando MS SQL 2008, che FUNZIONA , infatti, hanno il tipo di dati bit.


1
FWIW, quella domanda SO a cui hai fatto riferimento si riferisce a come .NET rappresenta questi tipi in memoria. Non ha nulla a che fare con il modo in cui SQL Server li rappresenta. bit <= char. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt

1
Per cosa stai usando il campo del genere? Potrebbe essere solo una stringa, in modo che le persone possano inserire ciò che vogliono? Cercare di enumerare tutte le possibili risposte a questa domanda sarà complicato.
spostato

@ThePassenger: Penso che la solita opzione sia fondamentalmente m / f / altro, quindi sì, come ternary come tu suggerisci, va bene. Potresti voler distinguere "altro" da "non specificato" (come in "Non sto dicendo", e / o "non abbiamo ancora chiesto all'utente"). Non sono a conoscenza delle persone fluide in termini di genere che desiderano un valore in virgola mobile con un dispositivo di scorrimento che possono impostare ogni giorno; la mia ipotesi è che la maggior parte di loro (e altre persone di genere non tradizionale) sarebbero felici di scegliere "altro" o "non specificato" su quasi tutti i siti Web. Ma no, non penso che chiedere "sesso" anziché "genere" sarebbe una buona idea.
Peter Cordes,

1
@PeterCordes Non sono a conoscenza del "fluido di genere", nel mio villaggio sei un uomo, una donna ... o una mucca. Se il genere è ora fluido, la creazione di una scala di valore per quanto riguarda il suono del computer sembra un po 'troppo da chiedere. Nel mio paese preferiamo il sesso, è meno complicato. Oh, non credere che siamo nell'età della pietra finora, eh! Abbiamo già scoperto Dio e siamo monoteisti per la maggior parte dall'ultima colonizzazione.
Revolucion per Monica il

2
@PeterCordes: poiché esigere tali cose nell'attuale clima politico offrirà vantaggi alle persone fornendo loro il dominio sugli altri, non appena includerai un cursore a valore variabile, qualcuno si farà avanti chiedendo uno multidimensionale. "Solo un cursore? Sei nell'età della pietra?"
vsz

Risposte:


82

Definirei la colonna "genere".

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

Il tipo di dati BIT può essere escluso perché supporta solo due sessi possibili che è inadeguato. Sebbene INT supporti più di due opzioni, sono necessari 4 byte: le prestazioni saranno migliori con un tipo di dati più piccolo / più stretto.

CHAR(1)ha il vantaggio su TinyINT : entrambi accettano lo stesso numero di byte, ma CHAR fornisce un numero più stretto di valori. L'utilizzo CHAR(1)renderebbe l'uso di "m", "f", ecc. Chiavi naturali, rispetto all'uso di dati numerici che sono chiamati chiavi surrogate / artificiali. CHAR(1)è supportato anche su qualsiasi database, qualora fosse necessario eseguire il porting.

Conclusione

Vorrei usare l'opzione 2: CHAR (1).

appendice

Un indice sulla colonna del genere probabilmente non sarebbe utile perché non esiste alcun valore in un indice su una colonna con cardinalità bassa. Significato, non c'è abbastanza varietà nei valori per l'indice per fornire alcun valore.


Qualche riferimento alle prestazioni? So che è quasi micro-ottimizzazione che non dovrei fare, ma è cibo per la mia mente curiosa.
Marko,

Grazie @OMG Pony, per quanto riguarda le prestazioni? Un personaggio sarebbe più costoso di un po 'in questo caso?
Marko,

4
@Marko: Come ho detto prima, sono uguali. Ma un indice probabilmente non sarebbe utile perché non esiste alcun valore in un indice su una colonna con cardinalità bassa. Significato, non c'è abbastanza varietà nei valori per l'indice per fornire alcun valore.
OMG Pony

1
Quanto migliore è la prestazione in realtà sta per essere utilizzando, per esempio, un tipo di dati di 4 byte su una piattaforma a 64 bit? Sto solo dicendo ... ;-)
Craig

1
Vorrei rimanere con un po ', poiché ci sono solo due sessi. Tuttavia, rimane la domanda iniziale di OP: quale sarebbe il nome della colonna? "IsMale" o "IsFemale" è un po 'strano ...
Mateus Felipe,

180

Esiste già uno standard ISO per questo; non c'è bisogno di inventare il tuo schema:

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

Secondo lo standard, la colonna dovrebbe essere chiamata "Sesso" e il tipo di dati "più vicino" sarebbe minuscolo con un vincolo CHECK o una tabella di ricerca, a seconda dei casi.


4
Perché passa a 9 per "non applicabile"? Che dire di 3-8?
Kenmore,

4
Questo è per il sesso. OP ha specificamente richiesto il genere. Sesso e genere probabilmente hanno diversi possibili valori che potrebbero dover essere catturati.
indigochild,

2
@indigochild L'OP utilizza entrambe le parole nel titolo della domanda e le considera chiaramente equivalenti, almeno per il suo caso d'uso (YMMV). Il mio punto è semplicemente che esiste uno standard ISO in questo settore e non dovresti mai perdere tempo a ideare il tuo schema quando esiste uno standard ufficiale. A meno che, naturalmente, tale standard non copra il tuo caso particolare, il che è del tutto possibile.
Pondlife,

1
Questa dovrebbe essere la risposta accettata. Si concentra sull'integrità dei dati (che è ~ per sempre) anziché sull'ottimizzazione (che è situazionale).
Paul Cantrell,

1
Questa dovrebbe essere sicuramente la risposta. @PeterCordes questa ISO è usata per il sesso (sesso biologico) e non per il genere (quello che identifichi come) - spiegazione qui . Immagino che nel caso in cui volessi memorizzare il genere (che, non saprei quale uso hai fatto in questo modo), un piccolo int è ancora abbastanza buono fintanto che vuoi memorizzare meno di 255 generi (dicendo fe 0 = sconosciuto / non voler dichiarare, 1 = uomo, 2 = donna, 3 = uomo che si identifica come donna, ecc.)
SolidTerre,

43

In medicina ci sono quattro generi: maschio, femmina, indeterminato e sconosciuto. Potresti non aver bisogno di tutti e quattro ma sicuramente hai bisogno di 1, 2 e 4. Non è appropriato avere un valore predefinito per questo tipo di dati. Ancor meno per trattarlo come un booleano con stati 'is' e 'non'.


1
@EJP, interessante. Hai un riferimento a questo?
Marko,

11
Mio padre, MD BS FRACP.
Marchese di Lorne,

Sulla base di queste informazioni, andrei in TinyIntlinea con un enum (come suggerisce Hugo) e andrei con almeno 1, 2 e 3 (Altro).
Estratto

1
@EJP, sebbene la tua risposta sia probabilmente corretta, NON dice quale tipo di dati dovrei usare, ma piuttosto - quali sono i sessi (tecnicamente) corretti.
Marko,

17
Il dizionario dei dati del servizio sanitario nazionale del Regno Unito definisce quattro valori: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, che mirrow i valori ISO 5218 . Nota che ci sono due tipi : genere al momento della registrazione (di solito poco dopo la nascita) e attuale.
giorno

3

Un Int(o TinyInt) allineato a unEnum campo sarebbe la mia metodologia.

Innanzitutto, se hai un singolo bitcampo in un database, la riga utilizzerà comunque un byte intero, quindi per quanto riguarda il risparmio di spazio, ripaga solo se hai piùbit campi.

In secondo luogo, le stringhe / i caratteri hanno un "valore magico", indipendentemente da quanto possano sembrare evidenti in fase di progettazione. Per non parlare, consente alle persone di archiviare qualsiasi valore che non necessariamente mapperebbero a qualcosa di ovvio.

Terzo, un valore numerico è molto più semplice (e pratica migliore) per cui creare una tabella di ricerca, al fine di imporre l'integrità referenziale e può correlare 1-a-1 con un enum, quindi c'è parità nella memorizzazione del valore in memoria all'interno l'applicazione o nel database.


2

Uso char 'f', 'm' e 'u' perché suppongo il genere da nome, voce e conversazione, e talvolta non conosco il genere. La determinazione finale è la loro opinione.

Dipende davvero da quanto conosci la persona e se i tuoi criteri sono la forma fisica o l'identità personale. Uno psicologo potrebbe aver bisogno di opzioni aggiuntive: incrocio a femmina, incrocio a maschio, trans a femmina, trans a maschio, ermafrodita e indeciso. Con 9 opzioni, non chiaramente definite da un singolo personaggio, potrei seguire il consiglio di Hugo di un piccolo numero intero.


Non in tema. Non è una risposta
hod

1

L'opzione 3 è la soluzione migliore, ma non tutti i motori DB hanno un tipo "bit". Se non ne hai un po ', allora TinyINT sarebbe la soluzione migliore.


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

inserisci qui la descrizione del link


-5

Vorrei andare con l'opzione 3 ma più colonne di bit NON NULLABLE anziché una. IsMale (1 = Sì / 0 = No) IsFemale (1 = Sì / 0 = No)

se richiesto: IsUnknownGender (1 = Sì / 0 = No) e così via ...

Ciò consente una facile lettura delle definizioni, una facile estensibilità, una facile programmabilità, nessuna possibilità di utilizzare valori esterni al dominio e nessun requisito di una seconda tabella di ricerca + vincoli FK o CHECK per bloccare i valori.

EDIT: correzione, è necessario almeno un vincolo per assicurarsi che i flag impostati siano validi.


Sarebbe bello sapere perché la mia risposta viene annullata?
HansLindgren,

Senza vincoli, nulla impedisce a tutte le colonne di essere 1 o tutte a 0. Il che sarebbe privo di senso, quindi il tuo schema non soddisfa una delle tue affermazioni.
Jay Kominek,

Sì, hai ragione a dire che hai bisogno di un vincolo per verificare che il numero corretto di flag sia "controllato". Non credo che tutti i voti
negativi

È una domanda molto visitata (guarda i voti per alcune delle altre risposte!), E sei arrivato anni dopo e hai aggiunto una risposta che equivale a una codifica a caldo, una tecnica ampiamente insegnata, che non ha nemmeno il poche proprietà concrete che gli attribuisci. Non credo sia giusto votare sotto 0, ma non mi sorprende neanche che sia successo.
Jay Kominek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.