В каком типе переменной хранить пол, bool, enum (перечисление), другие варианты? И почему?
Пишу на C# и вроде бы запросто можно изпользовать булево :) Но посоветовался с опытным 1С-ником, а он говорит, что ни в коем случае!!! Что в 1С и пол и Юр.Лицо\Физ.Лицо и прочие подобные параметры - это перечисления из 2 значений. Но разве не проще: bool isWoman = true (or false) ;
???
Заранее, спасибо всем, кто адекватно ответит!
abcd0x00: true, false, null - но гибкости не будет. Зачастую, помимо М и Ж, могут возникнуть дети, младенцы, и как было сказано, разделение на юридических, физических лиц и т.п. Так что проще сразу использовать перечисления, чтобы потом не пришлось переделывать :-)
abcd0x00: дети вроде как люди, на них bool не хватит :-) Можно городить множество полей и хранить все отдельно, но для этого придется делать большую работу. Если заранее учитывать, то тратить время в пустую. Практика показывает, что М и Ж бизнесу мало, и заранее неизвестно, что понадобится. В молодости гендерные bool приходилось меять. Разделением тоже как-то занимался - идиотизм полный, ибо делить можно бесконечно. Вот так бывало нужно отправить в API пол человека, у тебя для этого десять полей: пол, возраст, обращение и т.п. с портянкой условий, а в API всего одно числовое или строковое значение.
Лучше перечислений для подобной задачи еще ничего не придумали :-) Хранение бесполезных точных данных, типа возраста, не имеет смысла, если эти эти данные понадобятся только для одноразового определения является человек ребенком и в какую возрастную группу он попадает (портянка условий) и для прочих разделений.
Алексей Немиро: ты пытаешься в колонке пола хранить тип человека (мужчина, женщина, ребёнок, бабушка), а нужно две колонки иметь - пол человека и возрастной тип. Если нужно будет у ребёнка сохранить пол, ты что будешь делать? Ты будешь достраивать что-то там, и в конце получится какая-то индусская картина, потому что поменять ты не сможешь ничего, из-за того что много кода будет полагаться на изначальную архитектуру базы данных. Ещё хреновее - хранить пол у организации, у которой вообще пола нет. В таких случаях у тебя будет типа заполнитель несуществующей колонки, что является затычкой, которые потом накапливаются и вообще всё тормозят.
abcd0x00: В больших базах каждый байт на счету, нужно взвешенно подходить к проектированию. Один байт (true | false) против одного байта (0-255), ну или двух, если значений будет не хватать. Последний явно дает больше возможностей для развития. Если все станет плохо, то конечно, придется делать существенные доработки или даже новую базу. Но такого по идее быть не должно, поскольку хоть какая-то информация о проекте перед началом разработки должна быть и можно учесть многое. Мне еще ни разу не приходилось переделывать перечисления, а вот bool - да. Единственное, с масками нужно осторожней быть, не увлекаться сильно, а лучше не использоваться совсем (с большими значениями и вычислениями в больших базах можно существенно потерять в производительности).
Со смешением физических лиц с организациями - вариант с перечислениями лучше, база будет выглядеть проще и работать быстрее. Различные вариации, когда в базе десять тысяч таблиц под разные типы, в большинстве своем, одинаковых данных, также как и невостребованные поля, - выглядят ужасно и громоздко.
Из практического примера - системы бронирования авиабилетов. На поверхности у них четыре типа пассажиров: младенец, ребенок, взрослый мужик и не менее взрослая баба. И далее могут быть разные вариации типов пассажиров. Все в одном перечислении. Хотя конечно, это не пол как таковой, но используется для идентификации пола. Мне попадались различные ужасные вариации реализации этого, а в крупных проектах приходилось тотально все переделывать. Всего-то можно было изначально сделать одно простое перечисление :-)
Если границ развития проекта никаких нет, то да, будет лучше все разделить, точнее скорее строить вертикально. Но количество подобных проектов-монстров в меньшинстве и это другой уровень, другие ресурсы. Обычно все просто. Десяток вариаций «полов» и никаких bool :-) Если СУБД позволяет, можно автоматизировать распределение хранения данных по разным признакам. Все должно быть просто и быстро.
Строки тоже иногда используются. Это в принципе неплохо, если база небольшая и работать приходится с сырыми данными. Для небольших проектов в целом без разницы как хранить данные, переделать будет проще.
Из практического примера - системы бронирования авиабилетов. На поверхности у них четыре типа пассажиров: младенец, ребенок, взрослый мужик и не менее взрослая баба. И далее могут быть разные вариации типов пассажиров. Все в одном перечислении. Хотя конечно, это не пол как таковой
Да, это не пол, это тип или класс пассажира. Просто тебе пол не нужен и как бы ты его узнаёшь иногда только.
А вот теперь представь, что через 10 лет использования такой базы у тебя появляется новый самолёт, где два туалета - мужской и женский. И тебе нужно составить запрос, сколько человек посетило женский туалет за год. И ты что будешь писать? Правильно, ты будешь сидеть и набирать эти поля вручную, выбирая из них, кто женщина, кто не женщина, а кто вообще - стиральная машина. А все потому, что тебе нужно было сделать таблицу людей и таблицу билетов, и просто соединить эти две таблицы изначально, а ты решил сэкономить типа "а что будет".
abcd0x00: почему же, будет обычное условие :-) ...WHERE pass_type = FEMALE С детьми возникнут проблемы, если изначально их не разделять по гендерному признаку.
Люди и билеты, как правило, в разных таблицах. Смешивать их нет смысла, это совсем разные структуры.
Но даже если каким-то образом все это окажется в одной таблице, выборка будет аналогичной.
Если типов людей немного и использовать маски, то все совсем просто:
-- слова вместо чисел, просто для примера
WHERE (pass_type & 'FEMALE') = 'FEMALE' -- только женщины
WHERE (pass_type & 'FEMALE') = 'FEMALE' AND (pass_type & 'CHILD') = 'CHILD' -- дети женского пола
WHERE (pass_type & 'FEMALE') = 'FEMALE' AND (pass_type & 'INFANT') = 'INFANT'
Но запросы будут ресурсоемкими, особенно если данных много. Лучше так не делать или не использовать как есть.
Для небольших баз такой вариант может быть удобным, если типов людей будет не больше 10-15 (210) и данных немного (с несколькими гигабайтам проблем точно не должно возникнуть, даже на слабом железе).
Возможные ситуации с полами. Например, если изначально были М, Ж и пол не указан. Может потребоваться расширить этот список, сделать несколько вариантов "пол не указан". Если использовать bool, то придется добавлять дополнительное поле, которое будет содержать информацию, почему пол не указан, или переделывать в int. А в перечисления достаточно добавить нужные элементы в список и все: пол не указан, потому что гладиолус; луна находилось в неправильном месте; пользователь пьян; пользователь не дошел до выбора пола; facebook не вернул информацию о поле пользователя; пользователь отказался отвечать на вопрос и т.п. Бредовый список, но как минимум два варианта "пол не указан" в реальных условиях может быть: не выбран и null.
Алексей Немиро: я где-то выше писал, что должно быть как минимум три возможных значения для пола - мужской, женский и неопределён. Поправлю себя же: должно быть четыре варианта - мужской, женский, неясный и значение не задано. Так что bool тут точно не подходит. Но вот хранить в поле пола, что у него пол - ребёнок, это как раз не даёт у детей задавать пол. И это вылезет, когда потом потребуется выборка именно по полу.
У тебя просто в примере с билетами пол не используется вообще, только тип пассажира. Просто там пол неважен, поэтому дети и взрослые считаются как бы одного пола.
1C-ник правильно вам сказал - для таких случаев в 1С используются перечисления. Так проще сопровождать. Не придется разбираться кто есть кто - мужчина или женщина.
Для гибкости (и по идеологии шарпа) можно сделать структурой, инкапсулирующей этот Int32/Nullable/Enum и т.д., умеющий в конвертирование из разных представлений, выдачу локализованных названий полов, сериализацию и прочие полезные вещи.