Моля, прочетете за Нормализация на данните , Общо индексиране концепции и Външен ключ ограничения за поддържане на данните чисти с референтна цялост. Това ще ви накара да продължите.
Съхраняването на данни в масиви може да ви изглежда естествено на хартия, но за 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 (a.k.a 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 |
+-----------+--------------+----------+--------------------+
Ким е претоварена, така че зарежете часа по математика
delete from SCJunction
where studentId=2 and courseId=4 and term=100
стартирайте това по-горе изявление за избор, показващо какво приема Ким:
+-----------+--------------+----------+--------------------+
| StudentId | FullName | courseId | courseName |
+-----------+--------------+----------+--------------------+
| 2 | Kim Billings | 5 | World of Chaucer |
| 2 | Kim Billings | 1 | Early Roman Empire |
+-----------+--------------+----------+--------------------+
А, много по-лесен термин. Татко обаче няма да е доволен.
Обърнете внимание на такива неща като SCJunction.term. Много може да се напише за това, в момента ще го пропусна най-вече, освен да кажа, че трябва да е и във FK някъде. Може да искате терминът ви да изглежда по-скоро като ПРОЛЕТ 2015, а не като цяло.
И що се отнася до id. Това е начинът, по който бих го направил. Това е лично предпочитание. Ще е необходимо да знаете идентификационните номера и да ги търсите. Други биха могли да изберат да имат идентификатор на курса нещо като HIST101, а не 17. Те са много по-четливи (но по-бавни в индекса (едва). Така че правете това, което е най-добро за вас.
Сложен индекс на бележка
Съставният индекс (ИНДЕКС означава КЛЮЧ и обратно) е този, който комбинира множество колони за бързо извличане на данни. Поръчките се обръщат за двата композита в таблицата SCJunction, така че в зависимост от вселената от заявки, които вървят след вашите данни, db машината може да избере кой индекс да използва за най-бързо извличане въз основа на най-лявата колона, която търсите .
Що се отнася до уникалния ключ, #1, коментарът до него, в който се посочва, че не се прилагат дубликати (което означава нежелани данни), е по-скоро разбираем. Например студент 1 курс 1 семестър 1 не може да съществува два пъти в тази таблица.
Решаваща концепция за разбиране е концепцията за left-most
подреждане на имената на колони в индекс.
За заявки, които вървят след studentId
само , след това ключа, който има studentId
изброени първи (left-most
) се използва. В заявки, които вървят след courseId
само , след това ключа, който има courseId
използва се най-ляво. При заявки, които вървят след studentId и courseId, db машината може да реши кой съставен ключ да използва.
Когато казвам „върви след“, имам предвид в клаузата on clause
или where clause
състояние.
Ако някой нямаше тези два съставни ключа (с обърнати колони 1 и 2 в тях), тогава при заявки, където търсената колона не е left-most
Индексирани, няма да имате полза от използването на ключове и ще претърпите бавно сканиране на таблици за връщане на данни.
И така, тези два индекса комбинират следните 2 понятия
- Бързо извличане на данни въз основа на най-ляво или и двете (колони studentId и courseId)
- Налагане на недублиране на данни в тази таблица въз основа на studentId, courseId и стойности на термина
Вземането за вкъщи
Важното за вставане е, че таблиците на Junction осигуряват бързо извличане на индекси и разумно управление на данни срещу данни, разделени със запетая (нагласа на масива), натъпкани в колона, и цялата мизерия от използването на такава конструкция.