сохранение нескольких значений в одном поле

Я хочу, чтобы пользователи могли выбирать их специальности.

Например, человек А мог выбрать компьютерную науку, математику и историю как свои специальности. Пользователи могут выбрать любое количество майоров.

У меня есть список организаций в моей базе данных, которые будут принимать студентов только в том случае, если они имеют особую значимость. Например, Организация A принимает только специальности информатики и математики. Организации могут выбрать любое количество майоров.

Я хочу соответствовать студентам организациям, которые соответствуют их специальностям. Например, я хочу искать базу данных для организаций, которые принимают одну или несколько специальностей Person's A, которые являются информатикой, математикой и историей. Организации, которые принимают всех или большинство лиц A-лиц, будут указаны первыми. Поэтому, если организация B принимает все три должности специалиста A, но Организация A принимает только две должности специалиста A, организация B будет указана первыми.

Как хранить майоры, которые организации принимают в базе данных mysql? Как я могу хранить майоры студентов, чтобы обеспечить эффективное сопоставление между информацией о студентах и ​​информацией о организации?

Я рассматривал возможность хранения всех майоров, которые организации принимают в виде сериализованных значений в базе данных.

Итак, у меня есть 2 стола

организации
ID int
имя varchar (255)
majors_accepted blob

Студенты
ID int
имя varchar (255)
майоры blob

Я мог бы хранить майоры, которые организации принимают как сериализованные значения в majors_accepted blob. В этой области может быть более 1 мажор.

Или я мог бы хранить майоры, которые студенты рассматривают как сериализованные значения в области майоров в таблице «Студенты». В этой области может быть более 1 мажор. Тогда, я думаю, я мог бы перебирать все строки в таблице организаций и сравнивать каждое поле majors_accepted со студенческими данными. Но это кажется неэффективным …

Я бы сделал это так:

  1. создать таблицу майоров – имеет majorID и majorName
  2. создайте таблицу ассоциаций между учащимися и специальностями, у которых есть studentID и majorID.
  3. создайте таблицу ассоциаций между организациями и крупными компаниями, у которых есть orgID и majorID.

Это не хороший дизайн базы данных для хранения более одного значения в поле, как то, что вы пытаетесь сделать с вашими блоками, поэтому нарушите это так, и вы можете делать все запросы, необходимые для определения того, к каким организациям может присоединиться учащийся просто соединяя таблицы.

Предположим, вы ищете организации, к которым может присоединиться один конкретный ученик (мы скажем, что studentID для этого ученика – 1):

SELECT Students.ID, Organizations.name FROM Students INNER JOIN StudentsMajors ON Students.ID = StudentsMajors.studentID INNER JOIN OrganizationsMajors ON StudentsMajors.majorID = OrganizationsMajors.majorID INNER JOIN Oranizations ON OrganizationsMajors.orgID = Organizations.ID WHERE Students.ID = 1 

Не пытайтесь хранить основные списки как капли в одном столбце, для этого используйте отдельные таблицы ассоциаций:

 create table organization_majors ( organization_id int not null, major_id int not null, primary key (organization_id, major_id) ); create table student_majors ( student_id int not null, major_id int not null, primary key (student_id, major_id) ); 

Вы можете также индексировать каждый столбец в первичных ключах индивидуально, но индексирование зависит (как обычно) от того, какие запросы вы, вероятно, будете использовать.

Затем вы можете использовать стандартные SQL-запросы для проверки соответствия майоров. Например, чтобы найти всех студентов с major_id из 1:

 select s.id, s.name from students s join student_majors m on s.id = m.student_id where m.major_id = 1 

или найти всех студентов, которые могут быть в организации 11:

 select s.id, s.name from students s join student_majors sm on s.id = sm.student_id join organization_majors om on sm.major_id = om.major_id where om.organization_id = 11 group by s.id, s.name having count(*) = (select count(*) from organization_majors where organization_id = 11) 

Отношения между студентами и специальностями – это многие ко многим. Лучший дизайн для многих-ко-многим – это таблица ассоциаций, как уже говорили другие респонденты. Таблица ассоциации будет ссылаться на таблицу учеников и на таблицу майоров с данными, такими как имя майора.

Сохранение нескольких значений в одном поле с разделителем, таким как запятая, является плохим дизайном. Он нарушает первую нормальную форму. Когда вы нарушаете первую нормальную форму, вы больше не можете выполнять поиск по ключевым словам для всех данных.

В качестве примера вам нужно выполнить полное сканирование таблицы, чтобы найти всех студентов с данным основным. Это может привести к тысячам дисковых ios, а не менее сотни дисковых ios для трехстороннего соединения. Это в десять раз медленнее.

Когда вы планируете поиск по ключевым словам в таблице ассоциации, обратите пристальное внимание на хороший индексный дизайн. Хороший оптимизатор запросов наряду с хорошим дизайном индекса может получить максимальную скорость из ваших соединений. К счастью, вы можете вернуться и изменить дизайн индекса без выгрузки и перезагрузки таблицы.