Изгледи – създаване на view

Често се случва да се налага да пишем един и същи SELECT.  Например всички служители, които имат кредити. Може би е добре тази заявка да бъде записана някъде, а още по-добре е да може да я достъпваме и използваме сякаш резултатът от нея е истинска таблица.

В MySQL изгледите (view) представляват таблици, получени в резултат от SELECT заявки, съхранени с определено име в базата данни.

Синтаксис:

CREATE VIEW <име> (имена на колони)

AS SELECT <имена на колони> … ;

Можете да пропуснете (имена на колони),  така ще участват всички колони, които участват и в select.

 

Например в предна статия търсехме списък с имената на учениците и класовете им, както и номера (id) на групата в която тренират за всички ученици, които тренират в понеделник от 08:00 и са при треньор с име „Иван Тодоров Петров“, но само за групите му по футбол.

Нека по този select да създадем view:

create view footbalGroupsOfIvPetrov 
AS 
SELECT students.name, students.class, sportgroups.id
 FROM students JOIN sportgroups
 ON students.id IN (
	SELECT student_id
	FROM student_sport
	WHERE student_sport.sportGroup_id = sportgroups.id
 )
 WHERE sportgroups.id IN(
	SELECT sportgroup_id
    FROM student_sport
    WHERE sportGroup_id IN(
		SELECT id
		FROM sportgroups
		WHERE dayOfWeek = 'Monday'
		AND hourOfTraining = '08:00:00'
		AND coach_id IN(
			SELECT id
			FROM coaches
			WHERE name = 'Иван Тодоров Петров'
		)
        AND sport_id =(
			SELECT id
			FROM sports
            WHERE name = 'Football'
		)
    )
 );

Можете да видите всички изгледи:
6
Можете да третирате изгледа като нормална таблица, но с някои особености, разбира се.

SELECT * FROM footbalgroupsofivpetrov;

Ще изведе:
7
Важно:

  • Ако във вложения оператор SELECT участват ORDER BY, GROUP BY, HAVING, DISTINCT и UNION, то ако ги използвате, полученото VIEW става необновяемо (read – only), защото данните в него ще са обобщени и промените върху тях няма как да се отразят върху реалните таблици. Такова VIEW е много удачно да наричаме “изглед“, защото то ще става само за четене(заявки SELECT).
  • Важно е да има съответствие между върнатите колони от оператора SELECT и изброените след името на VIEW.
  • Можем да изпълняваме и заявки от тип INSERT, UPDATE и DELETE – те ще бъдат трансформирани автоматично от системата за управление на бази данни .
  • Използването на INSERT, UPDATE и DELETE през VIEW не се препоръчва!
  • Най-често VIEW се използва „само за четене“ и съответно потребителите се рестриктират да имат само права SELECT върху тези таблици.

 

 

За да изтриете view използвайте :

DROP VIEW <име> CASCADE;

  • Ключовата дума CASCADE означава, че ако има производно на това VIEW (т.е. VIEW създадено чрез изтриваното VIEW), то също ще бъде изтрито. Съществува синтактично, но не работи функционално, което означава. че в други СУБД работи и е добре да го знаете.
  • Алтернативата е с ключова дума RESTRICT, където ако има производно VIEW, то ще бъде върната грешка.
  • По принцип не е добра идея да създавате производни едни на други изгледи.
  •  Стойността по подразбиране на DROP VIEW e CASCADE.

За за изпълнявате INSERT зявки върху VIEW, трябва в INSERT да поставите всички колони от дадената таблица, чиито стойности са NOT NULL.

За да може да направите едно view да бъде updatable, то трябва да спазите следните правила:

Вашият изглед не трябва да съдържа нито едно от долуизброените:

  • Агрегатна функция
  • DISTINCT
  • GROUP BY клауза.
  • HAVING клауза.
  • UNION или UNION ALL клауза.
  • Left join или outer join.
  • Подзаявка в SELECT или в WHERE клауза, която да извлича информация от таблица, която се споменава във FROM клаузата на същата заявка.
  • SELECT, който извежда информация от друго non-updatable view във FROM клаузата си.

Даниел Джолев

 

3 thoughts on “Изгледи – създаване на view”

  1. Задачи от упражнение:
    1.SELECT students.name, students.class, students.phone
    FROM students
    JOIN student_sport on students.id = student_sport.student_id
    join sports on sports.id = student_sport.sportGroup_id
    where sports.name =’Football’;

    2.SELECT coaches.name
    From coaches
    Join sportgroups on coaches.id = sportgroups.coach_id
    JOIN sports on sports.id = sportgroups.sport_id
    WHERE sports.name = ‘Volleyball’;

    3.SELECT coaches.name, sports.name
    From coaches
    JOIN sportgroups on coaches.id = sportgroups.coach_id
    join sports on sports.id = sportgroups.sport_id
    JOIN student_sport on sportgroups.id = student_sport.sportGroup_id
    JOIN students on students.id = student_sport.student_id
    WHERE students.name=’Iliyan Ivanov’;

    4.SELECT sportgroups.id, COUNT(*)
    from sportgroups
    join student_sport on student_sport.sportGroup_id= sportgroups.id
    Group by sportgroups.id;

    5.SELECT SUM(paymentAmount)
    from taxesPayments join students
    on taxesPayments.student_id = students.id
    join sportgroups
    on taxespayments.group_id= sportGroups.id
    join coaches
    on sportGroups.coach_id = coaches.id
    WHERE year = ‘2016’
    and coaches.egn = ‘7509041245’
    and taxespayments.paymentAmount > 700
    Group by month;

  2. В примера за групите по футбол на Иван Петров не се ли прави излишен селект?
    Това е моето решение и работи:
    create view footbalGroupsOfIvanPetrov
    AS
    SELECT students.name, students.class, sportgroups.id
    FROM students JOIN sportgroups
    ON students.id IN (
    SELECT student_id
    FROM student_sport
    WHERE student_sport.sportGroup_id = sportgroups.id
    )

    WHERE sportgroups.dayOfWeek = ‘Monday’
    AND sportgroups.hourOfTraining = ’08:00:00′
    AND coach_id IN(
    SELECT id
    FROM coaches
    WHERE name = ‘Иван Тодоров Петров’
    )
    AND sport_id =(
    SELECT id
    FROM sports
    WHERE name = ‘Football’
    );

    1. Здравейте,
      Правилна ви е заявката. Има различни варианти за решение на задачата. В зависимост от обемите данни и степента на нормализация на базата, различните решения могат да дадат по-добър или по-лош резултат.

Leave a Reply

Your email address will not be published. Required fields are marked *