Основно съдържание
Програмиране
Курс: Програмиране > Раздел 3
Урок 3: Релационни заявки в SQL- Разделяне на данни в свързани таблици
- Съединяване на свързани таблици
- Предизвикателство: Боби има хоби
- Свързване на свързани таблици с външно ляво свързване (left outer join)
- Предизвикателство: Поръчки от клиенти
- Съединяване на таблици към самите себе си със себе-съединяване
- Предизвикателство: Филми в SQL
- Комбиниране на няколко съединения
- Предизвикателство: КнигаПриятели
- Проект: Известни хора
- По-ефективен SQL чрез планиране на заявки и оптимизация
© 2023 Khan AcademyУсловия за ползванеДекларация за поверителностПолитика за Бисквитки
Разделяне на данни в свързани таблици
Досега работехме само с една таблица и видяхме колко интересни данни можем да извлечем от нея. Но в действителност в повечето случаи данните ни са разпределени в няколко таблици, а таблиците са "свързани" една с друга по някакъв начин.
Да речем например, че имаме таблица за това колко добре се справят учениците на тестовете. Искаме да включим и имейл адреси, в случай, че искаме да изпратим имейл на родителите заради ниски оценки:
student_name | student_email | test (тест) | grade (оценка) |
---|---|---|---|
Питър Зайков | peter@rabbit.com | Хранителен | 95 |
Алиса Чудестранна | alice@wonderland.com | Хранителен | 92 |
Питър Зайков | peter@rabbit.com | Химия | 85 |
Алиса Чудестранна | alice@wonderland.com | Химия | 95 |
Може да имаме и таблица със записи на книгите, които чете всеки ученик:
student_name | book_title (заглавие на книгата) | book_author (автор) |
---|---|---|
Питър Зайков | Приказка за Г-жа Тиги-Уинкъл | Беатрикс Потър |
Питър Зайков | Джабъруоки | Луис Карол |
Алиса Чудестранна | Ловът на акулата | Луис Карол |
Алиса Чудестранна | Джабъруоки | Луис Карол |
Освен това ни трябва и таблица с подробна информация за ученика:
id | student_first (първо име) | student_last (фамилия) | student_email | phone (телефон) | birthday (роден на) |
---|---|---|---|---|---|
1 | Питър | Зайков | peter@rabbit.com | 555-6666 | 2001-05-10 |
2 | Алиса | Чудестранна | alice@wonderland.com | 555-4444 | 2001-04-02 |
Какво мислиш за тези таблици? Дали можеш да ги промениш по някакъв начин?
Има едно важно нещо, което трябва да разбереш за тези таблици: те описват релационни данни – данни, които са свързани едни с други. Всяка таблица описва данни, свързани с конкретен ученик, а данните се повтарят в много от таблиците. Когато данните се повтарят в няколко таблици, може да има интересни последствия.
Ами ако се промени имейл адресът на ученика? Кои таблици трябва да промениш?
Ще трябва да променим таблицата с информация за ученика, но тъй като тази информация е включена в таблицата с оценките, трябва да намерим всеки ред за ученика и да променим имейл адреса.
Често е за предпочитане да се уверим, че дадена колона с данни е запазена само на едно място, за да има по-малко места, които да променяме и по-малък риск за различни данни на различни места. Ако го направим, трябва да се уверим, че имаме начин, по който да свържем данните през таблиците, до което ще стигнем по-късно.
Да речем, че сме решили да махнем имейл адреса от таблицата с оценките, защото сме разбрали, че се повтаря с този в таблицата с детайли за ученика. Имаме ето това:
student_name | test (тест) | grade (оценка) |
---|---|---|
Питър Зайков | Хранителен | 95 |
Алиса Чудестранна | Хранителен | 92 |
Питър Зайков | Химия | 85 |
Алиса Чудестранна | Химия | 95 |
Как можем да разберем имейл адреса на всеки ученик? Можем да намерим реда в таблицата с информация за ученика като търсим по име. Ами ако има 2-ма ученика с едно и също име? (Знаеш ли, че в Бали всеки има само 1 от 4 възможни първи имена?) Не можем да разчитаме на името, за да намерим ученика. Всъщност не трябва никога да използваме нещо като име за уникален идентификатор в една таблица.
Затова най-добре е да махнем името на ученика (
student_name
) и да го заместим със student_id
, тъй като това със сигурност е уникален идентификатор:student_id | test (тест) | grade (оценка) |
---|---|---|
1 | Хранителен | 95 |
2 | Хранителен | 92 |
1 | Химия | 85 |
2 | Химия | 95 |
Можем да направим същата промяна и в таблицата с книгите като използваме
student_id
вместо student_name
:student_id | book_title (заглавие на книгата) | book_author (автор) |
---|---|---|
1 | Приказка за Г-жа Тиги-Уинки | Беатрикс Потър |
1 | Джабъруоки | Луис Карол |
2 | Ловът на акулата | Луис Карол |
2 | Джабъруоки | Луис Карол |
Забелязваш ли, че заглавието и авторът се повтарят за Джабъруоки? Това е знак, че трябва да разделим таблицата на допълнителни таблици, за да не се налага да я актуализираме няколко пъти, ако нещо за книгата се промени.
Можем да имаме таблица само за книги:
id | book_title (заглавие на книгата) | book_author (автор) |
---|---|---|
1 | Приказка за Г-жа Тиги-Уинки | Беатрикс Потър |
2 | Джабъруоки | Луис Карол |
3 | Ловът на акулата | Луис Карол |
А таблицата
student_books
става:student_id | book_id |
---|---|
1 | 1 |
1 | 2 |
2 | 3 |
2 | 2 |
Разбирам, че тази таблица не изглежда толкова ясна, като предната, в която имахме информация, сбита във всеки ред. Но таблиците обикновено не са предназначени за чете от хора – те са проектирани така, че да са лесни за поддръжка и възможно най-малко податливи на бъгове. В много случаи би било най-добре информацията да се разпредели на множество свързани таблици, така че да има по-малко повтарящи се данни и по-малко места за обновяване.
Важно е да разбираш как да използваш SQL, за да работиш с данни, разделени в няколко релационни таблици, и как да събереш данните от таблиците, когато е необходимо. Използваме понятие, наречено "join", и сега ще ти покажа какво означава то.
Искаш ли да се присъединиш към разговора?
Все още няма публикации.