Stockage du sexe (genre) dans la base de données

130

Je souhaite stocker le sexe d'un utilisateur dans une base de données avec un coût (taille / performances) aussi faible que possible.

Jusqu'à présent, 3 scénarios me viennent à l'esprit

  1. Int - aligné sur Enum dans le code (1 = Male, 2 = Female, 3 = ...)
  2. char (1) - Stocke m , f ou un autre identificateur de caractère unique
  3. Bit (booléen) - y a-t-il un nom de champ approprié pour cette option?

La raison pour laquelle je pose la question est à cause de cette réponse qui mentionne que les caractères sont plus petits que les booléens .

Je dois préciser que j'utilise MS SQL 2008, qui FONCTIONNE ont en fait le type de données bit.

Marko
la source
1
FWIW, cette question SO que vous avez référencée fait référence à la façon dont .NET représente ces types en mémoire. Cela n'a rien à voir avec la façon dont SQL Server les représente. bit <= car. msdn.microsoft.com/en-us/library/ms177603.aspx
mat
1
Pourquoi utilisez-vous le champ de genre? Serait-ce juste une chaîne pour que les gens puissent saisir ce qu'ils aiment? Essayer d'énumérer toutes les réponses possibles à cette question va être délicat.
shoggé
@ThePassenger: Je pense que l'option habituelle est essentiellement m / f / autre, donc oui ternaire comme vous le suggérez, c'est bien. Vous voudrez peut-être distinguer «autre» de «non spécifié» (comme dans «je ne le dis pas» et / ou «nous n'avons pas encore demandé à l'utilisateur»). Je ne suis pas au courant que des personnes de genre fluide souhaitent une valeur à virgule flottante avec un curseur qu'ils peuvent définir tous les jours; je suppose que la plupart d'entre eux (et d'autres personnes non traditionnelles) seraient heureux de choisir simplement «autre» ou «non spécifié» sur presque tous les sites Web. Mais non, je ne pense pas que demander «sexe» au lieu de «genre» serait une bonne idée.
Peter Cordes
1
@PeterCordes Je ne connais pas très bien le "gender-fluid", dans mon village, vous êtes soit un homme, une femme ... ou une vache. Si le genre est désormais fluide, créer une échelle de valeur quant au son de l'ordinateur semble un peu trop demander. Dans mon pays on demande plutôt le sexe, c'est moins compliqué. Oh, ne croyez pas que nous sommes à l'âge de pierre pour l'instant, hein! Nous avons déjà découvert Dieu et nous sommes pour la plupart monothéistes depuis la dernière colonisation.
Revolucion pour Monica
2
@PeterCordes: comme exiger de telles choses dans le climat politique actuel donnera aux gens des avantages en leur donnant une domination sur les autres, dès que vous incluez un curseur de valeur flottante, quelqu'un se présentera pour en exiger un multidimensionnel. "Juste un curseur? Êtes-vous à l'âge de pierre?"
vsz

Réponses:

83

J'appellerais la colonne «sexe».

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

Le type de données BIT peut être exclu car il ne prend en charge que deux genres possibles, ce qui est inadéquat. Alors qu'INT prend en charge plus de deux options, il prend 4 octets - les performances seront meilleures avec un type de données plus petit / plus étroit.

CHAR(1)a l'avantage sur TinyINT - les deux prennent le même nombre d'octets, mais CHAR fournit un nombre plus restreint de valeurs. Utiliser CHAR(1)ferait utiliser des clés naturelles "m", "f", etc., par rapport à l'utilisation de données numériques qui sont appelées clés de substitution / artificielles. CHAR(1)est également pris en charge sur n'importe quelle base de données, en cas de besoin de port.

Conclusion

J'utiliserais l'option 2: CHAR (1).

Addenda

Un index sur la colonne de genre n'aiderait probablement pas, car il n'y a aucune valeur dans un index sur une colonne de cardinalité faible. Cela signifie qu'il n'y a pas assez de variété dans les valeurs pour que l'index fournisse une valeur.

Poneys OMG
la source
Une référence à la performance? Je sais que c'est presque de la micro-optimisation, ce que je ne devrais pas faire, mais c'est de la nourriture pour mon esprit curieux.
Marko
Merci @OMG Ponies, qu'en est-il des performances? Un personnage serait-il plus coûteux qu'un peu dans ce cas?
Marko
4
@Marko: Comme je l'ai déjà dit, ils sont égaux. Mais un index n'aiderait probablement pas car il n'y a aucune valeur dans un index sur une colonne de cardinalité faible. Cela signifie qu'il n'y a pas assez de variété dans les valeurs pour que l'index fournisse une valeur.
OMG Ponies
1
Dans quelle mesure les performances seront-elles vraiment meilleures en utilisant, par exemple, un type de données de 4 octets sur une plate-forme 64 bits? Juste en disant ... ;-)
Craig
1
Je m'en tiens à peu, car il n'y a que deux sexes. Cependant, la question initiale de OP demeure: quel serait le nom de la colonne? "IsMale" ou "IsFemale" est un peu étrange ...
Mateus Felipe
180

Il existe déjà une norme ISO pour cela; pas besoin d'inventer votre propre schéma:

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

Selon la norme, la colonne doit être appelée "Sex" et le type de données "le plus proche" serait tinyint avec une contrainte CHECK ou une table de recherche selon le cas.

Pondlife
la source
4
Pourquoi passe-t-il à 9 pour «sans objet»? Et pour 3-8?
Kenmore
4
C'est pour le sexe. OP a spécifiquement demandé le sexe. Le sexe et le genre ont probablement des valeurs possibles différentes qu'il peut être nécessaire de saisir.
indigochild
2
@indigochild L'OP utilise les deux mots dans le titre de la question et les considère clairement comme équivalents, au moins pour son cas d'utilisation (YMMV). Je veux simplement dire qu’une norme ISO existe dans ce domaine et que vous ne devriez jamais perdre de temps à concevoir votre propre système quand une norme officielle existe. À moins bien sûr que cette norme ne couvre pas votre cas particulier, ce qui est tout à fait possible.
Pondlife
1
Cela devrait être la réponse acceptée. Il se concentre sur l'intégrité des données (qui est ~ pour toujours) au lieu de l'optimisation (qui est situationnelle).
Paul Cantrell
1
Cela devrait certainement être la réponse. @PeterCordes cette ISO est utilisée pour le sexe (sexe biologique) et non le genre (ce que vous identifiez comme) - explication ici . Je suppose que dans le cas où vous souhaitez stocker le genre (ce qui, je ne saurais pas quelle utilisation vous avez de faire cela), un petit int est toujours assez bon tant que vous voulez stocker moins de 255 genres (en disant fe 0 = inconnu / ne pas vouloir déclarer, 1 = homme, 2 = femme, 3 = homme s'identifiant comme femme, etc.)
SolidTerre
43

En médecine, il existe quatre genres: masculin, féminin, indéterminé et inconnu. Vous n'avez peut-être pas besoin des quatre, mais vous aurez certainement besoin de 1, 2 et 4. Il n'est pas approprié d'avoir une valeur par défaut pour ce type de données. Encore moins pour le traiter comme un booléen avec des états «est» et «n'est pas».

Marquis de Lorne
la source
1
@EJP, intéressant. Avez-vous une référence à cela?
Marko
11
Mon père, MD BS FRACP.
Marquis de Lorne
Sur la base de ces informations, j'irais avec TinyIntaligné avec une énumération (comme le suggère Hugo) et avec au moins 1, 2 et 3 (Autre).
IAbstract
1
@EJP, bien que votre réponse soit probablement correcte, elle ne dit PAS quel type de données je devrais utiliser, mais plutôt - quels sont les genres (techniquement) corrects.
Marko
17
Le dictionnaire de données du UK National Health Service (NHS) définit quatre valeurs: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, qui reflètent les valeurs ISO 5218 . Notez qu'il existe deux types : le sexe à l'enregistrement (généralement peu de temps après la naissance) et actuel.
jour du
3

Un Int(ou TinyInt) aligné sur un Enumchamp serait ma méthodologie.

Premièrement, si vous avez un seul bitchamp dans une base de données, la ligne utilisera toujours un octet complet, donc en ce qui concerne les économies d'espace, cela ne paie que si vous avez plusieurs bitchamps.

Deuxièmement, les chaînes / caractères ont pour eux une sensation de «valeur magique», quelle que soit leur évidence au moment de la conception. Sans oublier, cela permet aux gens de stocker à peu près n'importe quelle valeur qu'ils ne mapperaient pas nécessairement à quelque chose d'évident.

Troisièmement, une valeur numérique est beaucoup plus facile (et meilleure pratique) pour créer une table de recherche, afin de renforcer l'intégrité référentielle, et peut corréler 1 à 1 avec une énumération, il y a donc parité dans le stockage de la valeur en mémoire dans l'application ou dans la base de données.

Hugo
la source
2

J'utilise char «f», «m» et «u» parce que je suppose le sexe à partir du nom, de la voix et de la conversation, et parfois je ne connais pas le genre. La décision finale est leur opinion.

Cela dépend vraiment de la façon dont vous connaissez la personne et si vos critères sont la forme physique ou l'identité personnelle. Un psychologue pourrait avoir besoin d'options supplémentaires - croisé vers femme, croisé vers homme, trans vers femme, trans vers homme, hermaphrodite et indécis. Avec 9 options, pas clairement définies par un seul caractère, je pourrais suivre les conseils d'Hugo d'un petit entier.

Zarac
la source
Pas sur le sujet. Ce n'est pas une réponse.
hod le
1

L'option 3 est votre meilleur choix, mais tous les moteurs DB n'ont pas un type "bit". Si vous n'en avez pas, alors TinyINT serait votre meilleur pari.

ajacian81
la source
-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;

entrez la description du lien ici

Mohammad Asif
la source
-5

J'irais avec l'option 3 mais plusieurs colonnes de bits NON NULLABLE au lieu d'une. IsMale (1 = Oui / 0 = Non) IsFemale (1 = Oui / 0 = Non)

si nécessaire: IsUnknownGender (1 = Oui / 0 = Non) et ainsi de suite ...

Cela permet une lecture facile des définitions, une extensibilité facile, une programmabilité facile, aucune possibilité d'utiliser des valeurs en dehors du domaine et aucune exigence d'une deuxième table de recherche + contraintes FK ou CHECK pour verrouiller les valeurs.

EDIT: Correction, vous avez besoin d'au moins une contrainte pour vous assurer que les indicateurs définis sont valides.

HansLindgren
la source
Ce serait bien d'entendre pourquoi ma réponse est rejetée?
HansLindgren
Sans contraintes, rien n'empêche toutes les colonnes d'être 1, ou toutes d'être 0. Ce qui serait insensé, donc votre schéma ne satisfait pas l'une de vos revendications.
Jay Kominek le
Oui, vous avez raison de dire que vous avez besoin d'une contrainte pour vérifier que le nombre correct d'indicateurs est «vérifié». Je ne pense pas que tous les votes
négatifs
C'est une question très visitée (regardez les votes positifs pour certaines des autres réponses!), Et vous êtes venu des années plus tard et avez ajouté une réponse qui équivaut à un encodage à chaud, une technique largement enseignée, qui n'a même pas le quelques propriétés concrètes que vous lui attribuez. Je ne pense pas que ce soit juste de vous voter en dessous de 0, mais je ne suis pas surpris que ce soit arrivé non plus.
Jay Kominek le