Almacenar sexo (género) en la base de datos

130

Quiero almacenar el género de un usuario en una base de datos con el menor costo (tamaño / rendimiento) posible.

Hasta ahora, me vienen a la mente 3 escenarios

  1. Int - alineado con Enum en el código (1 = Masculino, 2 = Femenino, 3 = ...)
  2. char (1) : almacena m , f u otro identificador de un solo carácter
  3. Bit (booleano) : ¿hay un nombre de campo apropiado para esta opción?

La razón por la que pregunto es por esta respuesta que menciona que los caracteres son más pequeños que los booleanos .

Debo aclarar que estoy usando MS SQL 2008, que TIENE , de hecho, tienen el tipo de datos bit.

Marko
fuente
1
FWIW, esa pregunta SO a la que hizo referencia se refiere a cómo .NET representa estos tipos en la memoria. No tiene nada que ver con cómo los representa SQL Server. bit <= char. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt
1
¿Para qué estás usando el campo de género? ¿Podría ser solo una cadena, para que las personas puedan ingresar lo que quieran? Intentar enumerar todas las respuestas posibles a esta pregunta va a ser complicado.
Shogged
@ThePassenger: Creo que la opción habitual es básicamente m / f / other, así que sí, ternario, como sugiere, está bien. Es posible que desee distinguir "otro" de "no especificado" (como en "No lo digo" y / o "aún no le hemos preguntado al usuario"). No estoy al tanto de que las personas con fluidez de género quieran un valor de punto flotante con un control deslizante que puedan configurar todos los días; Supongo que la mayoría de ellos (y otras personas de género no tradicional) estarían felices de elegir "otro" o "no especificado" en casi cualquier sitio web. Pero no, no creo que sea buena idea pedir "sexo" en lugar de "género".
Peter Cordes
1
@PeterCordes No conozco bien el "fluido de género", en mi pueblo eres hombre, mujer ... o vaca. Si el género ahora es fluido, crear una escala de valor en cuanto al sonido de la computadora parece demasiado pedir. En mi país preferimos pedir sexo, es menos complicado. ¡Oh, no creas que estamos en la Edad de Piedra hasta ahora, eh! Ya hemos descubierto a Dios y somos monoteístas en su mayor parte desde la última colonización.
Revolución para Mónica
2
@PeterCordes: como exigir tales cosas en el clima político actual dará ventajas a las personas al proporcionarles dominio sobre los demás, tan pronto como incluya un control deslizante de valor flotante, alguien se presentará exigiendo uno multidimensional. "¿Solo un control deslizante? ¿Estás en la edad de piedra?"
vsz

Respuestas:

82

Llamaría a la columna "género".

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

El tipo de datos BIT se puede descartar porque solo admite dos géneros posibles, lo cual es inadecuado. Si bien INT admite más de dos opciones, requiere 4 bytes: el rendimiento será mejor con un tipo de datos más pequeño / más estrecho.

CHAR(1)tiene la ventaja sobre TinyINT : ambos toman el mismo número de bytes, pero CHAR proporciona un número más estrecho de valores. El uso CHAR(1)haría que usar "m", "f", etc., las teclas naturales, en comparación con el uso de datos numéricos que se denominan claves sustitutas / artificiales. CHAR(1)también es compatible con cualquier base de datos, en caso de que sea necesario portar.

Conclusión

Usaría la Opción 2: CHAR (1).

Apéndice

Un índice en la columna de género probablemente no ayudaría porque no hay valor en un índice en una columna de baja cardinalidad. Es decir, no hay suficiente variedad en los valores para que el índice proporcione ningún valor.

Ponis OMG
fuente
¿Alguna referencia al rendimiento? Sé que es casi una micro-optimización que no debería hacer, pero es alimento para mi mente curiosa.
Marko
Gracias @OMG Ponies, ¿qué pasa con el rendimiento? ¿Sería un char más costoso que un poco en este caso?
Marko el
44
@Marko: Como dije antes, son iguales. Pero un índice probablemente lo haría no ayudaría porque no hay valor en un índice en una columna de baja cardinalidad. Es decir, no hay suficiente variedad en los valores para que el índice proporcione ningún valor.
OMG Ponis
1
¿Cuánto mejor es realmente el rendimiento? va a ser usando, por ejemplo, un tipo de datos de 4 bytes en una plataforma de 64 bits? Solo digo ... ;-)
Craig
1
Me quedaría con poco, ya que solo hay dos géneros. Sin embargo, la pregunta inicial de OP sigue siendo: ¿cuál sería el nombre de la columna? "IsMale" o "IsFemale" es un poco extraño ...
Mateus Felipe el
180

Ya existe un estándar ISO para esto; No es necesario inventar su propio esquema:

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

Según el estándar, la columna debe llamarse "Sexo" y el tipo de datos 'más cercano' sería tinyint con una restricción CHECK o tabla de búsqueda según corresponda.

Estanque
fuente
44
¿Por qué se salta a 9 por 'no aplicable'? ¿Qué pasa con 3-8?
Kenmore
44
Esto es por sexo. OP solicitó específicamente género. El sexo y el género probablemente tienen diferentes valores posibles que pueden necesitar ser capturados.
indigochild
2
@indigochild El OP utiliza ambas palabras en el título de la pregunta y las considera claramente equivalentes, al menos para su caso de uso (YMMV). Mi punto es simplemente que existe un estándar ISO en esta área y nunca debe perder tiempo en diseñar su propio esquema cuando existe un estándar oficial. A menos que, por supuesto, ese estándar no cubra su caso particular, lo cual es completamente posible.
Pondlife
1
Esta debería ser la respuesta aceptada. Se centra en la integridad de los datos (que es ~ para siempre) en lugar de la optimización (que es situacional).
Paul Cantrell
1
Esta definitivamente debería ser la respuesta. @PeterCordes esta ISO se usa para Sexo (sexo biológico) y no para Género (lo que identifica como) - explicación aquí . Supongo que en el caso de querer almacenar el género (que, no sabría qué uso tienes haciendo esto), un pequeño int todavía es lo suficientemente bueno siempre que quieras almacenar menos de 255 géneros (diciendo fe 0 = desconocido / no queriendo declarar, 1 = hombre, 2 = mujer, 3 = hombre que se identifica como mujer, etc.)
SolidTerre
43

En medicina hay cuatro géneros: masculino, femenino, indeterminado y desconocido. Es posible que no necesite los cuatro, pero ciertamente necesita 1, 2 y 4. No es apropiado tener un valor predeterminado para este tipo de datos. Incluso menos para tratarlo como un booleano con estados 'es' y 'no es'.

Marqués de Lorne
fuente
1
@EJP, interesante. ¿Tienes alguna referencia a esto?
Marko
11
Mi padre, MD BS FRACP.
Marqués de Lorne
Basado en esta información, iría con TinyIntalineado con una enumeración (como sugiere Hugo) e iría con al menos 1, 2 y 3 (Otro).
IAbstract
1
@EJP, aunque su respuesta probablemente sea correcta, NO dice qué tipo de datos debería usar, sino más bien cuáles son los géneros (técnicamente) correctos.
Marko
17
El diccionario de datos del Servicio Nacional de Salud del Reino Unido (NHS) define cuatro valores: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, que reflejan los valores de ISO 5218 . Tenga en cuenta que hay dos tipos : género en el registro (generalmente poco después del nacimiento) y actual.
cuando el
3

Un Int(o TinyInt) alineado a unEnum campo sería mi metodología.

Primero, si tiene un solo bitcampo en una base de datos, la fila seguirá utilizando un byte completo, por lo que, en lo que respecta al ahorro de espacio, solo vale la pena si tiene múltiplesbit campos.

En segundo lugar, las cadenas / caracteres tienen una sensación de "valor mágico", independientemente de lo obvio que puedan parecer en el momento del diseño. Sin mencionar que permite a las personas almacenar casi cualquier valor que no necesariamente asignarían a algo obvio.

Tercero, un valor numérico es mucho más fácil (y una mejor práctica) para crear una tabla de búsqueda, con el fin de hacer cumplir la integridad referencial, y puede correlacionar 1 a 1 con una enumeración, por lo que hay paridad en el almacenamiento del valor en la memoria dentro de la aplicación o en la base de datos.

Hugo
fuente
2

Uso char 'f', 'm' y 'u' porque supongo el género por nombre, voz y conversación, y a veces no sé el género. La determinación final es su opinión.

Realmente depende de qué tan bien conozca a la persona y si su criterio es la forma física o la identidad personal. Un psicólogo podría necesitar opciones adicionales: cruzado a femenino, cruzado a masculino, trans a femenino, trans a masculino, hermafrodita e indeciso. Con 9 opciones, no claramente definidas por un solo personaje, podría seguir el consejo de Hugo de pequeño número entero.

zarac
fuente
No sobre el tema. No es una respuesta.
Hod
1

La opción 3 es su mejor opción, pero no todos los motores DB tienen un tipo "bit". Si no tiene un poco, entonces TinyINT sería su mejor apuesta.

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

ingrese la descripción del enlace aquí

Mohammad Asif
fuente
-5

Iría con la Opción 3 pero múltiples columnas de bits NO NULABLES en lugar de una. IsMale (1 = Sí / 0 = No) IsFemale (1 = Sí / 0 = No)

si se requiere: IsUnknownGender (1 = Sí / 0 = No) y así sucesivamente ...

Esto facilita la lectura de las definiciones, la extensibilidad fácil, la facilidad de programación, la posibilidad de usar valores fuera del dominio y el requisito de una segunda tabla de búsqueda + restricciones FK o CHECK para bloquear los valores.

EDITAR: Corrección, necesita al menos una restricción para garantizar que los indicadores establecidos sean válidos.

HansLindgren
fuente
Sería bueno saber por qué mi respuesta es rechazada?
HansLindgren
Sin restricciones, nada impide que todas las columnas sean 1, o todas ellas sean 0. Lo cual no tendría sentido, por lo que su esquema no satisface una de sus afirmaciones.
Jay Kominek
Sí, tiene razón en que necesita una restricción para verificar que se 'verifique' el número correcto de banderas. Sin embargo, no creo que todos los votos
negativos
Es una pregunta muy visitada (¡mira los votos a favor de algunas de las otras respuestas!), Y apareciste años después y agregaste una respuesta que equivale a una codificación única, una técnica ampliamente enseñada, que ni siquiera tiene pocas propiedades concretas que le atribuyes. No creo que haya sido correcto votar por debajo de 0, pero tampoco me sorprende que haya sucedido.
Jay Kominek