Как хранить несколько опций в одной таблице?

Я хочу создать приложение для вычисления результата.

Во-первых, мне нужно знать, как хранить запись в базе данных MySQL таким образом, чтобы учащиеся могли иметь столько курсов, к которым они прикреплены, например, у ученика А могут быть прикреплены к нему 6 предметов, в то время как ученик B может иметь 12 предметов, прикрепленных к нему ,

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

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

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

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

Следующее должно заставить вас идти с хорошим началом, когда вы возитесь. Присоединяется тоже.

create table student ( studentId int auto_increment primary key, fullName varchar(100) not null -- etc ); create table dept ( deptId int auto_increment primary key, deptName varchar(100) not null -- Economics -- etc ); create table course ( courseId int auto_increment primary key, deptId int not null, courseName varchar(100) not null, -- etc CONSTRAINT fk_crs_dept FOREIGN KEY (deptId) REFERENCES dept(deptId) ); create table SCJunction ( -- Student/Course Junction table (aka Student is taking the course) -- also holds the attendance and grade id int auto_increment primary key, studentId int not null, courseId int not null, term int not null, -- term (I am using 100 in below examples for this term) attendance int not null, -- whatever you want, 100=always there, 0=he must have been partying, grade int not null, -- just an idea -- See (Note Composite Index) at bottom concerning next two lines. unique key(studentId,courseId,term), -- no duplicates allowed for the combo (note student can re-take it next term) key (courseId,studentId), CONSTRAINT fk_sc_student FOREIGN KEY (studentId) REFERENCES student(studentId), CONSTRAINT fk_sc_courses FOREIGN KEY (courseId) REFERENCES course(courseId) ); 

Создание тестовых данных

 insert student(fullName) values ('Henry Carthage'),('Kim Billings'),('Shy Guy'); -- id's 1,2,3 insert student(fullName) values ('Shy Guy'); insert dept(deptName) values ('History'),('Math'),('English'); -- id's 1,2,3 insert course(deptId,courseName) values (1,'Early Roman Empire'),(1,'Italian Nation States'); -- id's 1 and 2 (History dept) insert course(deptId,courseName) values (2,'Calculus 1'),(2,'Linear Algebra A'); -- id's 3 and 4 (Math dept) insert course(deptId,courseName) values (3,'World of Chaucer'); -- id 5 (English dept) -- show why FK constraints are important based on data at the moment insert course(deptId,courseName) values (66,'Fly Fishing 101'); -- will generate error 1452. That dept 66 does not exist -- That error is a good error to have. Better than faulty data -- Have Kim (studentId=2) enrolled in a few courses insert SCJunction(studentId,courseId,term,attendance,grade) values (2,1,100,-1,-1); -- Early Roman Empire, term 100 (made up), unknown attendance/grade insert SCJunction(studentId,courseId,term,attendance,grade) values (2,4,100,-1,-1); -- Linear Algebra A insert SCJunction(studentId,courseId,term,attendance,grade) values (2,5,100,-1,-1); -- World of Chaucer -- Have Shy Guy (studentId=3) enrolled in one course only. He is shy insert SCJunction(studentId,courseId,term,attendance,grade) values (3,5,100,-1,-1); -- Early Roman Empire, term 100 (made up), unknow attendance/grade -- note if you run that line again, the Error 1062 Duplicate entry happens. Can't take same course more than once per term 

Некоторые простые вопросы.

Какой курс находится в каком отделе?

показать все, использует псевдонимы таблиц (сокращений), чтобы сделать типизацию меньше, читаемость (иногда) лучше

 select c.courseId,c.courseName,d.deptId,d.deptName from course c join dept d on c.deptId=d.deptId order by d.deptName,c.courseName -- note the order +----------+-----------------------+--------+----------+ | courseId | courseName | deptId | deptName | +----------+-----------------------+--------+----------+ | 5 | World of Chaucer | 3 | English | | 1 | Early Roman Empire | 1 | History | | 2 | Italian Nation States | 1 | History | | 3 | Calculus 1 | 2 | Math | | 4 | Linear Algebra A | 2 | Math | +----------+-----------------------+--------+----------+ 

Кто берет курс мира Чосера на этот срок?

(зная курс Id = 5)

Ниже приведена одна из наших составных индексов в SCJunction. Компоновщик – это индекс на более чем одном столбце.

 select s.StudentId,s.FullName from SCJunction j join student s on j.studentId=s.studentId where j.courseId=5 and j.term=100 +-----------+--------------+ | StudentId | FullName | +-----------+--------------+ | 2 | Kim Billings | | 3 | Shy Guy | +-----------+--------------+ 

Ким Биллингс зачислен в этот термин?

 select s.StudentId,s.FullName,c.courseId,c.courseName from SCJunction j join student s on j.studentId=s.studentId join course c on j.courseId=c.courseId where s.studentId=2 and j.term=100 order by c.courseId DESC -- descending, just for the fun of it +-----------+--------------+----------+--------------------+ | StudentId | FullName | courseId | courseName | +-----------+--------------+----------+--------------------+ | 2 | Kim Billings | 5 | World of Chaucer | | 2 | Kim Billings | 4 | Linear Algebra A | | 2 | Kim Billings | 1 | Early Roman Empire | +-----------+--------------+----------+--------------------+ 

Ким переполнен, поэтому падение урона математического classа

 delete from SCJunction where studentId=2 and courseId=4 and term=100 

запустите этот оператор select select, показывающий, что делает Ким:

 +-----------+--------------+----------+--------------------+ | StudentId | FullName | courseId | courseName | +-----------+--------------+----------+--------------------+ | 2 | Kim Billings | 5 | World of Chaucer | | 2 | Kim Billings | 1 | Early Roman Empire | +-----------+--------------+----------+--------------------+ 

Ах, гораздо проще. Папа не будет счастлив.

Обратите внимание на такие вещи, как SCJunction.term. Многое может быть написано об этом, я пропущу его в данный момент в основном, кроме как сказать, что он также должен быть где-то в FK. Вы можете захотеть, чтобы ваш термин выглядел больше как SPRING2015, а не int.

И что касается id. Так я и сделал бы это. Это личное предпочтение. Это потребует знания id #, глядя на них. Другие могли бы выбрать курс, например, HIST101, а не 17. Они более читабельны (но медленнее в индексе (едва). Сделайте то, что лучше для вас.

Примечание. Композитный индекс

Компонентный индекс (INDEX означает KEY и наоборот) – это тот, который объединяет несколько столбцов для быстрого извлечения данных. Заказы перевернуты для двух композитов в таблице SCJunction, так что, в зависимости от юниверса запросов, которые идут за вашими данными, движок db может выбрать, какой индекс использовать для быстрого поиска, основываясь на самом левом столбце, который вы собираетесь после ,

Что касается уникального ключа, № 1, то комментарий рядом с ним, указывающий на то, что принудительное дублирование (что означает нежелательные данные), не требует пояснений. Например, студент 1 курс 1 термин 1 не может существовать дважды в этой таблице.

Важнейшей концепцией для понимания является концепция left-most порядка имен столбцов в индексе.

Для запросов, которые идут только после studentId , тогда используется ключ, в котором указан studentId первый ( left-most ). В запросах, которые идут только после courseId , тогда используется ключ, который имеет courseId left-most. В запросах, которые идут после studentId и courseId, механизм db может решить, какой составной ключ использовать.

Когда я говорю «идти за», я имею в виду on clause или where clause .

Если бы у них не было этих двух составных ключей (с перевернутыми столбцами 1 и 2), то в запросах, где искомый столбец не индексируется по left-most краю, вам не выгодно пользоваться ключами и страдать медленными таблицами для данных вернуться.

Итак, эти два индекса объединяют следующие 2 понятия

  • Быстрый поиск данных, основанный на самом левом или обоих (студенческие и курсовые)
  • Обеспечение не дублирования данных в этой таблице на основе значений studentId, courseId и term

Еда на вынос

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

Для полноты, не в том смысле, что это общее рекомендуемое решение:

MySQL предоставляет тип данных JSON , который позволяет хранить и извлекать объекты и массивы в формате JSON .

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

  ['subject_1', 'subject_2', 'subject_3'] 

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

По крайней мере JSON очень часто используется и легко анализируется как формат обмена данными.

Существуют допустимые варианты использования хранилищ массивов и объектов внутри поля MySQL, например, для оптимизации скорости или когда у вас есть неизвестные или динамические свойства, которые вы все еще хотите сохранить в БД.

Однако, как правило, если вы полагаетесь на хранение объектов и массива в MySQL, то, скорее всего, ваш дизайн базы данных будет нарушен.

  • MySQL - дизайн супертипа / подтипа
  • HTTP POST с параметрами запроса URL - хорошая идея или нет?
  • Как добиться анимации пульсации с помощью библиотеки поддержки?
  • Java AWT / SWT / Swing: как планировать графический интерфейс?
  • Как изменить новый цвет и высоту индикатора TabLayout
  • Android разнородный gridview как pinterest?
  • Есть ли опция / функция MySQL для отслеживания истории изменений записей?
  • Действительно ли метатег видового экрана необходим?
  • Кнопки раскраски в Android с материальным дизайном и AppCompat
  • Лучше ли создать одноэлементный доступ к контейнеру единства или передать его через приложение?
  • Заказ параметров для использования каррирования
  • Давайте будем гением компьютера.