Зберігання статі (статі) в базі даних


130

Я хочу зберігати стать користувача в базі даних з якомога меншими (розмірами / продуктивністю) витратами.

Поки на думку приходять 3 сценарії

  1. Int - узгоджується з кодом Enum (1 = Чоловік, 2 = Жіночий, 3 = ...)
  2. char (1) - Збережіть m , f або інший єдиний ідентифікатор символів
  3. Біт (булева) - чи є відповідна назва поля для цього параметра?

Я запитую тому , що з цього відповіді , який згадує , що символи мають менше , ніж булеві .

Я повинен уточнити, що я використовую MS SQL 2008, який НЕ насправді має бітовий тип даних.


1
FWIW, що ТАК, на який ви посилалися, стосується того, як .NET представляє ці типи в пам'яті. Це не має нічого спільного з тим, як їх представляє SQL Server. біт <= char. msdn.microsoft.com/en-us/library/ms177603.aspx
Matt

1
Для чого ви використовуєте гендерне поле? Чи може це бути просто рядок, щоб люди могли ввести те, що їм подобається? Спроба перерахувати всі можливі відповіді на це питання буде хитрою.
застрелився

@ThePassenger: Я думаю, що звичайний варіант в основному m / f / other, тому так потрійний, як ви пропонуєте, добре. Ви можете відрізнити "інших" від "невизначених" (як у "я не розповідаю" та / або "ми ще не запитували користувача"). Мені невідомо, що люди, які мають гендерну рідину, бажають значення з плаваючою комою за допомогою повзунка, який вони можуть встановлювати щодня; я здогадуюсь, що більшість із них (та інших людей, які не є традиційно ґендерними) були б раді просто вибрати "інших" або "не визначених" майже на будь-якому веб-сайті. Але ні, я не думаю, що прохання про "секс" замість "статі" було б гарною ідеєю.
Пітер Кордес

1
@PeterCordes Мені не добре відомо про "гендерну рідину", у моєму селі ваш чоловік, жінка ... або корова. Якщо жанр зараз є виваженим, створювати величину вартості, що стосується звуку на комп’ютері, здається, занадто багато, щоб запитати. У моїй країні ми швидше просимо сексу, це менш складно. О, не вірте, що ми поки що в кам'яному віці, так! Ми вже відкрили Бога і здебільшого є монотеїстами з часу останньої колонізації.
Революція для Моніки

2
@PeterCordes: оскільки вимоги до таких речей у нинішньому політичному кліматі дадуть людям переваги, надаючи їм домінування над іншими, як тільки ви включите повзунок з плаваючою цінністю, хтось висунеться з вимогою багатовимірного. "Лише один повзун? Ти в кам'яному віці?"
vsz

Відповіді:


82

Я б назвав стовпець "гендерним".

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 тип даних може бути виключена , оскільки він підтримує тільки два можливих підлог , який є недостатнім. Хоча INT підтримує більше двох варіантів, він займає 4 байти - продуктивність буде кращою при меншому / більш вузькому типі даних.

CHAR(1)має край над TinyINT - обидва беруть однакову кількість байтів, але CHAR надає більш вузьку кількість значень. Використання CHAR(1)може використовувати природні ключі "m", "f" тощо, порівняно з використанням числових даних, які називаються сурогатними / штучними ключами. CHAR(1)також підтримується в будь-якій базі даних, якщо є потреба в порту.

Висновок

Я б застосував варіант 2: CHAR (1).

Додаток

Індекс на гендерній колонці, ймовірно, не допоможе, оскільки в індексі стовпця з низькою кардинальністю немає значення. Тобто, не вистачає різноманітності у значеннях для індексу, щоб забезпечити будь-яке значення.


Будь-яке посилання на продуктивність? Я знаю, що це майже мікрооптимізація, чого я не повинен робити, але це їжа для мого допитливого розуму.
Марко

Дякуємо @OMG Ponies, а що з продуктивністю? Чи буде в цьому випадку принадність найдорожчою, ніж трохи?
Марко

4
@Marko: Як я вже говорив, вони рівні. Але індекс, ймовірно, не допоможе, оскільки в стовпці з низькою кардинальністю немає значення в індексі. Тобто, не вистачає різноманітності у значеннях для індексу, щоб забезпечити будь-яке значення.
OMG Ponies

1
Наскільки краще буде продуктивність на насправді збираєтеся використовувати, скажімо, тип даних 4 байт на 64-бітної платформі? Просто кажу… ;-)
Крейг

1
Я би дотримувався біта, оскільки є лише два статі. Однак, початкове питання ОП залишається: якою буде назва стовпця? "IsMale" або "IsF Female" трохи дивно ...
Матеус Феліпе

180

Для цього вже існує стандарт ISO; не потрібно вигадувати власну схему:

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

Відповідно до стандарту, стовпець повинен називатися "Sex", а "найближчий" тип даних буде tinyint із таблицею обмежень CHECK або таблицею пошуку відповідно.


4
Чому він переходить до 9 для "не застосовується"? А як щодо 3-8?
Кенмор

4
Це для сексу. ОП спеціально просила гендер. Стать і стать, ймовірно, мають різні можливі значення, які, можливо, потребують врахування.
indigochild

2
@indigochild ОП використовує обидва слова у назві запитання та чітко вважає їх рівнозначними, принаймні для випадку його використання (YMMV). Моя думка, просто, що в цій галузі існує стандарт ISO, і ви ніколи не повинні витрачати час на розробку власної схеми, коли існує офіційний стандарт. Якщо, звичайно, цей стандарт не охоплює ваш конкретний випадок, що цілком можливо.
Pondlife

1
Це має бути прийнятою відповіддю. Він фокусується на цілісності даних (що ~ назавжди) замість оптимізації (що ситуативно).
Пол Кантрелл

1
Це безумовно має бути відповіддю. @PeterCordes цей ISO використовується для сексу (біологічного сексу), а не для статі (що ви визначаєте як) - пояснення тут . Я думаю, що у випадку, коли ви хочете зберегти стать (що, я не знаю, для чого ви це робите), крихітний інт все ще досить хороший, якщо ви хочете зберігати менше 255 статей (кажучи, що fe 0 = невідомо / не хочуть заявляти, 1 = чоловік, 2 = жінка, 3 = чоловік, що ідентифікується як жінка тощо)
SolidTerre

43

У медицині існує чотири статі: чоловічий, жіночий, невизначений і невідомий. Можливо, вам не знадобляться всі чотири, але вам, безумовно, потрібні 1, 2 і 4. Для цього типу даних не доцільно мати значення за замовчуванням. Ще менше трактувати його як булеве зі станами "є" і "не".


1
@EJP, цікаво. Чи маєте ви посилання на це?
Марко

11
Мій батько, доктор медичних наук FRACP.
Маркіз Лорн

Виходячи з цієї інформації, я хотів би TinyIntзрівнятися з перерахунком (як пропонує Гюго) і піти з принаймні 1, 2 і 3 (Інше).
IАнотація

1
@EJP, хоча ваша відповідь, ймовірно, правильна, вона НЕ говорить про те, яким типом даних я повинен користуватися, а скоріше - які (технічно) правильні статі.
Марко

17
Словник даних Національної служби охорони здоров’я Великобританії (NHS) визначає чотири значення: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, які відображають значення ISO 5218 . Зауважте, існує два типи : стать при реєстрації (як правило, незабаром після народження) та поточний.
день, коли

3

Int(Або TinyInt) вирівнюються по Enumполю буде моя методика.

По-перше, якщо у вас є одне bitполе в базі даних, рядок все одно буде використовувати повний байт, тож, що стосується економії місця, він окупається лише за наявності кількох bitполів.

По-друге, рядки / символи мають до них "магічну цінність", незалежно від того, наскільки очевидними вони можуть здатися під час проектування. Не кажучи вже про те, що він дозволяє людям зберігати майже будь-яку цінність, яку вони не обов'язково відображають на щось очевидне.

По-третє, числове значення набагато простіше (і краща практика) створити таблицю пошуку для того, щоб забезпечити референтну цілісність, і може співвідносити 1-до-1 з перерахунком, тому є паритет зберігання значення в пам'яті додаток або в базі даних.


2

Я використовую char 'f', 'm' і 'u', тому що я здогадуюсь на гендері за іменем, голосом та розмовою, а іноді не знаю статі. Остаточне визначення - їх думка.

Це дійсно залежить від того, наскільки добре ви знаєте людину та чи є вашими критеріями фізична форма чи особистість. Психологу можуть знадобитися додаткові варіанти - перехреститись на жінку, перехрестити на чоловіка, транс на жіночу, транс на чоловічу, гермафродитну і не визначився. Маючи 9 варіантів, не чітко визначених одним символом, я можу погодитися з порадами Гюго про крихітні цілі числа.


Не на тему. Це не відповідь.
ход

1

Варіант 3 - найкраща ставка, але не всі двигуни БД мають тип "біт". Якщо у вас немає небагато, то 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;

введіть опис посилання тут


-5

Я б пішов із Варіантом 3, але декілька стовпців NON NULLABLE замість одного. IsMale (1 = Так / 0 = Ні) IsF Female (1 = Так / 0 = Ні)

якщо потрібно: IsUnknownGender (1 = Так / 0 = Ні) і так далі ...

Це полегшує зчитування визначень, легку розширюваність, просту програмованість, відсутність можливості використання значень поза доменом і не вимагає другої таблиці пошуку + обмеження FK або CHECK для фіксації значень.

EDIT: Виправлення, вам потрібно хоча б одне обмеження для забезпечення встановлених прапорів.


Було б приємно почути, чому моя відповідь оскаржується?
HansLindgren

Без обмежень ніщо не заважає всім стовпцям бути 1, або всім бути 0. Що було б безглуздо, тому ваша схема не задовольняє жодного з ваших претензій.
Джей Комінек

Так, ви праві, що вам потрібно одне обмеження, щоб перевірити правильність кількості прапорів "перевірено". Я не думаю, що всі голоси "за" - за цей пропуск ...
HansLindgren

Це дуже відвідуване запитання (подивіться на підсумки деяких інших відповідей!), І ви прийшли за роками пізніше і додали відповідь, яка становить одне гаряче кодування, широко вивчену техніку, яка навіть не має кілька конкретних властивостей, які ви їй приписуєте. Я не думаю, що було правильним голосувати за вас нижче 0, але я не здивований, що це теж сталося.
Джей Комінек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.