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


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.