Дизайн таблицы SQL для ISCO / Международная стандартная классификация профессий

#mysql #sql #database-design

#mysql #sql #проектирование базы данных

Вопрос:

Я пытаюсь выяснить, каков наилучший способ вставить международную стандартную классификацию профессий в MySQL.

Вот подробная информация о категориях: http://www.ilo.org/wcmsp5/groups/public/—dgreports/—dcomm/—publ/documents/publication/wcms_172572.pdf

Также я нашел проект github: https://github.com/patriciomacadden/isco/blob/master/db/schema.rb Похоже, что он использует отдельные таблицы для разных уровней групп.

Мое текущее мнение состоит в том, чтобы создать единую таблицу и сохранить некоторые повторяющиеся данные, поскольку данные не будут часто меняться, а объем данных меньше тысячи строк. Например:

 'l1','l2','l3','l4' are 'TINYINT' and 'level','name' are VARCHAR. So 'level' is the primary key

l1  |l2  |l3  |l4  |level|name
----|----|----|----|-----|--------
5   |null|null|null|5    |Services and Sales Workers
5   |1   |null|null|51   |Personal Services Workers
5   |1   |1   |null|511  |Travel Attendants, Conductors Guides
5   |1   |1   |1   |5111 |Travel Attendants and Travel Stewards
5   |1   |1   |2   |5112 |Transport Conductors
5   |1   |1   |3   |5113 |Travel Guides
  

Поле «уровень» — varchar, потому что мне может понадобиться получить все строки, включая верхнюю категорию.

ГДЕ уровень, ПОДОБНЫЙ «511%»

Я не уверен, что лучше иметь «уровень» как int, но, возможно, varchar имеет лучшие характеристики и при сортировке этих конкретных данных.

Я не уверен, нужны ли мне l1, l2, l3, l4 отдельно, но с таким небольшим количеством строк, возможно, не повредит некоторая избыточность.

Итак, вопрос в том, видите ли вы какие-либо очевидные ошибки в моем дизайне? Сможете ли вы улучшить это?

Я не уверен, нужно ли мне остерегаться дополнительных полей, потому что я еще не дочитал этот ISCO pdf…

Спасибо

Комментарии:

1. Это 433-страничный PDF-файл, возможно, объясните в абстрактных терминах, чего вы хотите. Тем не менее, значения L почти наверняка должны быть вертикальными, и было бы предпочтительнее избегать столбца «сводка», который дублирует данные, уже имеющиеся в строке (с неправильным типом данных).

2. Ну, я хочу импортировать ISCO в SQL наилучшим возможным способом. Достаточно ли это абстрактно? 🙂 Вы правы насчет L полей, и, вероятно, они мне вообще не нужны. Но я беспокоился, что могут быть случаи, о которых я не могу думать прямо сейчас, где они могут оказаться полезными.

Ответ №1:

Вам не нужны как l1 / l2 / l3 / l4, так и level: они полностью избыточны. Хранение одних и тех же данных двумя разными способами просто создает вероятность того, что где-то в процессе ошибка сделает их несовместимыми, и тогда вы получите странные результаты. Запрос, использующий l1/2/3/4 находит записи, отличные от запроса, использующего level, и пользователи недоумевают, почему их результаты не имеют смысла. Например, если на экране ввода данных используется level, и у вас есть код для разбиения его на l1/2/3/4 , пользователь запускает запрос, который под таблицей использует l1/2/3/4 и он находит ноль совпадающих записей. Затем он смотрит на экран, и запись прямо там! Или, что еще хуже, итоги не складываются и т. Д.

Трудно сказать, какой из двух отдать предпочтение. Большинство запросов, вероятно, проще писать с помощью одного поля: выберите бла-бла-бла, где level = ‘512’, или выберите бла-бла-бла, где level = ‘51%’, а затем выберите бла-бла-бла, где l1 = 5 и l2 = 1 и l3 = 2, а l4 равно нулю и т. Д. О, и тестирование более низких уровней без ссылки на более высокие уровни, вероятно, бессмысленно. То есть, когда бы вы когда-нибудь сказали выбрать бла-бла-бла, где l2 = 4, но не тестировать l1?

Уровень, безусловно, должен быть строкой, а не целым числом. Вы хотите, чтобы ’51’ сортировался до ‘512’, а не после. Вы бы никогда не стали делать арифметику над ними, верно? Что бы значило сказать chemist.level teacher.level или clerk.level * 3?

Ответ №2:

Я бы сделал

  • level VARCHAR(4) CHARACTER SET ascii . (Взгляд на PDF, кажется, говорит, что 4 достаточно, но при необходимости увеличьте «4».) VARCHAR будет сортировать «правильно», INT не будет.
  • SUBSTR(level, 3, 1) чтобы получить эквивалент l3, если вам нужно отобразить такой.
  • Вместо этого SUBSTR вы получите пустую строку NULL ; вы можете использовать IF(,) или CASE... отображать ее любым удобным для вас способом.