СУБД. Лекция 2

СУБД
Алехин Владислав
Лекция 2

Введение в проектирование. Введение в SQL.

Организационные моменты

Проектирование БД

Проектирование баз данных
Процесс создания схемы базы данных и определения необходимых ограничений целостности.
not-so-easy

Основные задачи

Сложная система, спроектированная наспех, никогда не работает, и исправить ее, чтобы заставить работать, невозможно.
Законы Мерфи.
16-й закон систематики

Особенности концептуального проектирования

Трудно что-либо предвидеть, а уж особенно будущее.
Нильс Бор

Этапы проектирования

Внешнее представление (внешняя схема) данных
Совокупность требований со стороны конкретной функции, выполняемой пользователем.
Концептуальная схема
Полная совокупность всех требований к данным, полученной из пользовательских представлений о реальном мире.
Внутренняя схема
Сама база данных.

Почему проект БД может быть плохим?

Блюдо Вид Дата Продукт Калорийность Вес (г) Поставщик Город Страна Цена ($)
Лобио Закуска 01.09.2012 Фасоль 307 200 "Хуанхэ" Пекин Китай 0.37
Лобио Закуска 01.09.2012 Лук 45 40 "Наталка" Киев Украина 0.52
Лобио Закуска 01.09.2012 Масло 742 30 "Лайма" Рига Латвия 1.55
Лобио Закуска 01.09.2012 Зелень 18 10 "Даугава" Рига Латвия 0.99
Борщ Суп 01.09.2012 Мясо 166 80 "Наталка" Киев Украина 2.18
Борщ Суп 01.09.2012 Лук 45 30 "Наталка" Киев Украина 0.52
Борщ Суп 01.09.2012 Томаты 24 40 "Полесье" Киев Украина 0.45
Борщ Суп 01.09.2012 Рис 334 50 "Хуанхэ" Пекин Китай 0.44
Борщ Суп 01.09.2012 Масло 742 15 "Полесье" Киев Украина 1.62
Борщ Суп 01.09.2012 Зелень 18 15 "Наталка" Киев Украина 0.88
  1. Избыточность
  2. Потенциальная противоречивость
    (аномалии обновления)
  3. Аномалии включения
  4. Аномалии удаления

Пример проекта

Задача: спроектировать базу для расчета стоимости работ веб-студии

Компания N занимается разработкой полного цикла и поддержкой веб-приложений.

Стоимость часа специалиста зависит от его должности.

Стоимость работ по проекту зависит от того сколько специалистов и по сколько часов работали над данным проектом

Необходимо спроектировать базу, которая позволит удобно вести учет работ по проектам и выставлять счета клиентам

Пример проекта

Формализация основных бизнес-требований

Пример сводной таблицы

ProjName EmpName JobType ChargePerHour HoursBilled TotalCharge
Meta Cortex Thomas A. Anderson Senior Software Engineer $10 25.4 $254.00
Michelle McGahey UI/UX Designer $5 15.0 $75.00
John Anderson Senior DBA $8 10.5 $84.00
Subtotal $413.00
ENCOM Kevin Flynn Senior Software Engineer $10 32.5 $325.00
Sam Flynn Junior Software Engineer $5 20.0 $100.00
John Anderson Software Engineer $8 30.0 $240.00
Alan Bradley Junior DBA $6 8.0 $48.00
Subtotal $713.00
Total $1126.00

1-ая нормальная форма

Переменная отношения находится в первой нормальной форме (1НФ) тогда и только тогда, когда в любом допустимом значении отношения каждый его кортеж содержит только одно значение для каждого из атрибутов.

1-ая нормальная форма

ProjName EmpName JobType ChargePerHour HoursBilled TotalCharge
Meta Cortex Thomas A. Anderson Senior Software Engineer $10 25.4 $254.00
Meta Cortex Michelle McGahey UI/UX Designer $5 15.0 $75.00
Meta Cortex John Anderson Senior DBA $8 10.5 $84.00
ENCOM Kevin Flynn Senior Software Engineer $10 32.5 $325.00
ENCOM Sam Flynn Junior Software Engineer $5 20.0 $100.00
ENCOM John Anderson Software Engineer $8 30.0 $240.00
ENCOM Alan Bradley Junior DBA $6 8.0 $48.00

Ключи или ключевые атрибуты

Ключ — атрибут или набор атрибутов, который однозначно идентифицирует кортеж в таблице в базе данных.


Первичный ключ — используется для идентификации объекта.

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


Составной ключ — использует несколько атрибутов.


Естественный ключ — набор атрибутов описываемой записью сущности, уникально её идентифицирующий.

Суррогатный ключ — искусственно сгенерированное поле, никак не связанное с информационным содержанием записи.

Первичный ключ

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

ProjNum ProjName EmpNum EmpName JobType ChargePerHour HoursBilled TotalCharge
15 Meta Cortex 105 Thomas A. Anderson Senior Software Engineer $10 25.4 $254.00
15 Meta Cortex 102 Michelle McGahey UI/UX Designer $5 15.0 $75.00
15 Meta Cortex 103 John Anderson Senior DBA $8 10.5 $84.00
12 ENCOM 108 Kevin Flynn Senior Software Engineer $10 32.5 $325.00
12 ENCOM 113 Sam Flynn Junior Software Engineer $5 20.0 $100.00
12 ENCOM 109 John Anderson Software Engineer $8 30.0 $240.00
12 ENCOM 101 Alan Bradley Junior DBA $6 8.0 $48.00

Первичный ключ

Составной суррогатный первичный ключ: < ProjNum, EmpNum >

ProjNum ProjName EmpNum EmpName JobType ChargePerHour HoursBilled TotalCharge
15 Meta Cortex 105 Thomas A. Anderson Senior Software Engineer $10 25.4 $254.00
15 Meta Cortex 102 Michelle McGahey UI/UX Designer $5 15.0 $75.00
15 Meta Cortex 103 John Anderson Senior DBA $8 10.5 $84.00
12 ENCOM 108 Kevin Flynn Senior Software Engineer $10 32.5 $325.00
12 ENCOM 113 Sam Flynn Junior Software Engineer $5 20.0 $100.00
12 ENCOM 109 John Anderson Software Engineer $8 30.0 $240.00
12 ENCOM 101 Alan Bradley Junior DBA $6 8.0 $48.00

Функциональная зависимость

Формальное определение:
Пусть дано отношение r со схемой R. A и B — некоторые подмножества множества R, то есть атрибутов отношения r. Множество B функционально зависит от A тогда и только тогда, когда каждое значение множества A связано в точности с одним значением множества B. Обозначается A -> B.
Менее формальное определение:
Если мы знаем, что для некоторого отношения выполняется правило: если кортежи отношения r совпадают по значению атрибута A, то они совпадают и по значению B. Тогда говорится, что B функционально зависит от A или A функционально определяет B.

Нормализация

Выделяем все функциональные зависимости:

ProjNum ProjName EmpNum EmpName JobType ChargePerHour HoursBilled TotalCharge
15 Meta Cortex 105 Thomas A. Anderson Senior Software Engineer $10 25.4 $254.00
12 ENCOM 113 Sam Flynn Junior Software Engineer $5 20.0 $100.00

2-ая нормальная форма

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

Простыми словами: не должно быть зависимости от части ключа.

  1. ProjNum, EmpNum -> ProjName, EmpName, JobType, ChargePerHour, HoursBilled, TotalCharge
  2. ProjNum -> ProjName
  3. EmpNum -> EmpName, JobType, ChargePerHour

2-ая нормальная форма

Простыми словами: не должно быть зависимости от части ключа.

Чтобы этого добиться разбиваем отношение с частичными зависимостями на несколько отдельных:

2-ая нормальная форма

Project

ProjNum ProjName
15 Meta Cortex
12 ENCOM

Assignment

ProjNum EmpNum HoursBilled
15 105 25.4
12 113 20.0

Employee

EmpNum EmpName JobType ChargePerHour
105 Thomas A. Anderson Senior Software Engineer $10
113 Sam Flynn Junior Software Engineer $5

3-я нормальная форма

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

Простыми словами: любой столбец таблицы должен зависеть только от ключевого столбца.

  1. EmpNum -> EmpName, JobType, ChargePerHour
  2. JobType -> ChargePerHour

Определения реляционной алгебры

Детерминант функциональной зависимости - набор атрибутов, который находится слева от стрелки в записи функциональной зависимости.

Тривиальная зависимость - зависимость, в которой правая часть является подмножеством детерминанта.

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

Транзитивность

Функциональная зависимость A -> B является транзитивной, если существует такое множество атрибутов C, что для него справедливы нетривиальные функциональные зависимости A -> C и C -> B, при этом отсутствует функциональная зависимость C -> A.

В реляционной алгебре транзитивность отличается от транзитивности в других разделах. Обязательность отсутствия зависимости C -> A не присуща другим разделам.

3-я нормальная форма

Другими простыми словами: не должно быть функциональных зависимостей среди неключевых атрибутов.

Чтобы этого добиться выделяем транзитивные зависимости в отдельные отношения

3-я нормальная форма

Project

ProjNum ProjName
15 Meta Cortex
12 ENCOM

Assignment

ProjNum EmpNum HoursBilled
15 105 25.4
12 113 20.0

Employee

EmpNum EmpName JobType
105 Thomas A. Anderson Senior Software Engineer
113 Sam Flynn Junior Software Engineer

Job

JobType ChargePerHour
Senior Software Engineer $10
Junior Software Engineer $5

Нормальная форма Бойса — Кодда (НФБК)

Формальное определение:
Переменная отношения находится в BCNF тогда и только тогда, когда каждая её нетривиальная и неприводимая слева функциональная зависимость имеет в качестве своего детерминанта некоторый потенциальный ключ.
Менее формальное определение:
Переменная отношения находится в нормальной форме Бойса — Кодда тогда и только тогда, когда детерминанты всех её функциональных зависимостей являются потенциальными ключами.

Нормальная форма Бойса — Кодда (НФБК)

Определение 3НФ не совсем подходит для следующих отношений:

Нормальная форма Бойса — Кодда (НФБК)

Для отношений, имеющих один потенциальный ключ (первичный), НФБК является 3НФ. Отношение находится в НФБК тогда и только тогда, когда она находится в третьей нормальной форме, и при этом не только любой неключевой атрибут полностью функционально зависит от любого ключа, но и любой ключевой атрибут должен полностью функционально зависеть от любого ключа.

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

Нормальная форма Бойса — Кодда (НФБК), Пример

Номер поставщика PNUM Наименование поставщика PNAME Номер детали DNUM Поставляемое количество VOLUME
1 Фирма 1 1 100
1 Фирма 1 2 200
1 Фирма 1 3 300
2 Фирма 2 1 150
2 Фирма 2 2 250
3 Фирма 3 3 1000

Отношение имеет два потенциальных ключа - {PNUM, DNUM} и {PNAME, DNUM}.

Нормальная форма Бойса — Кодда (НФБК), Пример

Номер поставщика PNUM Наименование поставщика PNAME
1 Фирма 1
2 Фирма 2
3 Фирма 3
Номер поставщика PNUM Номер детали DNUM Поставляемое количество VOLUME
1 1 100
1 2 200
1 3 300
2 1 150
2 2 250
3 3 1000

Нормальные формы. Подытожим.

Нормальная форма Определение
1 НФ Все значения атрибутов атомарны
2 НФ 1 НФ и нет частичных функциональных зависимостей
3 НФ 2 НФ и нет транзитивных зависимостей
НФ Бойса-Кодда 3 НФ и все детерминанты являются потенциальными ключами
4 НФ НФБД и не содержит нетривиальных многозначных зависимостей
5 НФ 4 НФ и каждая нетривиальная зависимость соединения в ней определяется потенциальным ключом (ключами) этого отношения
Доменно-ключевая НФ 5 НФ и каждое наложенное на неё ограничение является логическим следствием ограничений доменов и ограничений ключей, наложенных на данную переменную отношения
6 НФ 5 НФ и удовлетворяет всем нетривиальным зависимостям соединения, то есть недекомпозируема далее без потерь

Нормальные формы. Подытожим.

Мнемоническое правило:

Каждый атрибут атомарен (1НФ) и зависит...

... от ключа (2НФ)

... только от ключа (3НФ)

... и ни от чего кроме ключа (НФБК).

Виды связей между отношениями

Типы данных PostgreSQL

NULL

SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
1 = NULL 1 <> NULL 1 < NULL 1 > NULL
SELECT 1 IS NULL, 1 IS NOT NULL, NULL IS NULL, NULL IS NOT NULL;
1 IS NULL 1 IS NOT NULL NULL IS NULL NULL IS NOT NULL
0 1 1 0

Числовые

Тип столбца, поля Объём занимаемой памяти Диапазон допустимых значений
SMALLINT, INT2 2 байта От -32768 до 32767
INTEGER, INT, INT4 4 байта От -2147683648 до 2147683648
BIGINT, INT8 8 байт От -263 до 263 -1
DECIMAL [(M[,D])],
NUMERIC [(M[,D])]
~2 байта на 4 цифры Повышенная точность
более 10000 цифр
REAL 4 байта -3.402823466E+38 до -1.175494351E-38
1.175494351E-38 до 3.402823466E+38
DOUBLE PRECISION 8 байт -1.7976931348623157E+308
до -2.2250738585072014E-308
2.2250738585072014E-308
до 1.7976931348623157E+308
MONEY 8 байт От -92233720368547758.08 до +92233720368547758.07

SMALLSERIAL, SERIAL, BIGSERIAL - то же, но с автоинкрементом.

INT1 и беззнаковые есть в расширении https://github.com/petere/pguint

Бинарные

Тип столбца, поля Объём занимаемой памяти Диапазон допустимых значений
BIT(N) (N + 7) / 8 байт Битовая строка с фиксированной длиной
BIT VARYING(N), VARBIT(N) Битовая строка с переменной длиной
BOOLEAN 1 байт 0 или 1

Строки

Тип столбца, поля Описание
CHARACTER(N), CHAR(N) Строка фиксированной длины
CHARACTER VARYING(N), VARCHAR(M) Строка переменной длины
TEXT Строковые данные без ограничения длины
BYTEA Двоичный данные без ограничения длины

Дата и время

Тип столбца, поля Размер
TIMESTAMP [ (P) ] [ WITHOUT TIME ZONE ] 8 байт
TIMESTAMP [ (P) ] WITH TIME ZONE 8 байт
DATE 4 байта
TIME [ (P) ] [ WITHOUT TIME ZONE ] 8 байт
TIME [ (P) ] WITH TIME ZONE 12 байт
INTERVAL [ FIELDS ] [ (P) ] 16 байт

Время хранится с точностью до микросекунд.

P - кол-во цифр для хранения дробной части секунд.

WITH TIMEZONE - внутри базы хранится UTC.

CREATE TABLE

CREATE [ { TEMPORARY } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

Or:

CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    OF type_name [ (
  { column_name WITH OPTIONS [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE TABLE

column_constraint:

[ CONSTRAINT constraint_name ]
{ NOT NULL |
  NULL |
  DEFAULT default_expr |

  CHECK ( expression ) [ NO INHERIT ] |
  UNIQUE index_parameters |
  PRIMARY KEY index_parameters |
  REFERENCES reftable [ ( refcolumn ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

CREATE TABLE

table_constraint:

[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) [ NO INHERIT ] |
  UNIQUE ( column_name [, ... ] ) index_parameters |
  PRIMARY KEY ( column_name [, ... ] ) index_parameters |
  FOREIGN KEY ( column_name [, ... ] )
    REFERENCES reftable [ ( refcolumn [, ... ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE action ] [ ON UPDATE action ] }
  EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] )
    index_parameters [ WHERE ( predicate ) ] |
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

Обновление кортежа в родительском отношении (action)

NO ACTION
Не разрешать изменение
RESTRICT
То же, что и NO ACTION, но всегда IMMEDIATE
CASCADE
Изменить каскадно
SET NULL
Установить в NULL
SET DEFAULT
Установить значение по умолчанию

CREATE TABLE (пример)

CREATE TABLE films (
    code        char(5) CONSTRAINT firstkey PRIMARY KEY,
    title       varchar(40) NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    imdb        varchar(20) NULL,
    CONSTRAINT uniq_imdb UNIQUE(imdb)
);

CREATE TABLE distributors (
     did    integer PRIMARY KEY DEFAULT nextval('serial'),
     name   varchar(40) NOT NULL CHECK (name <> '')
);

ALTER TABLE

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    action [, ... ]
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME [ COLUMN ] column_name TO new_column_name
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME CONSTRAINT constraint_name TO new_constraint_name
ALTER TABLE [ IF EXISTS ] name
    RENAME TO new_name

action:

ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ ... ]
DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ USING expression ]
ALTER [ COLUMN ] column_name SET DEFAULT expression
ALTER [ COLUMN ] column_name DROP DEFAULT
ADD table_constraint [ NOT VALID ]
DROP CONSTRAINT [ IF EXISTS ]  constraint_name [ RESTRICT | CASCADE ]
...

ALTER TABLE (пример)

ALTER TABLE distributors
    ADD COLUMN address varchar(30),
    DROP COLUMN address RESTRICT,
    ALTER COLUMN address TYPE varchar(80),
    ALTER COLUMN name TYPE varchar(100);

ALTER TABLE foo
    ALTER COLUMN foo_timestamp DROP DEFAULT,
    ALTER COLUMN foo_timestamp TYPE timestamp with time zone
    USING
        timestamp with time zone 'epoch'
        + foo_timestamp * interval '1 second',
    ALTER COLUMN foo_timestamp SET DEFAULT now();

INSERT

[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
    [ ON CONFLICT [ conflict_target ] conflict_action ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

conflict_target:

( { index_column_name | ( index_expression ) } ... [, ...] )
[ WHERE index_predicate ]
ON CONSTRAINT constraint_name

conflict_target:

DO NOTHING
DO UPDATE SET { column_name = { expression | DEFAULT } |
                ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
                ( column_name [, ...] ) = ( sub-SELECT )
              } [, ...]
          [ WHERE condition ]

INSERT

INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy')
RETURNING *;

INSERT INTO films
SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';

INSERT INTO distributors (id, dname)
VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
ON CONFLICT (id) DO UPDATE SET dname = EXCLUDED.dname;

INSERT INTO distributors (id, dname) VALUES (7, 'Redline GmbH')
ON CONFLICT (id) DO NOTHING;

UPDATE

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

UPDATE

UPDATE table1
SET
    col_name1 = col_name2,
    col_name2 = col_name1
WHERE id = 42;

UPDATE weather
  SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
  WHERE city = 'San Francisco' AND date = '2003-07-03'
  RETURNING temp_lo, temp_hi, prcp;

UPDATE weather
  SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
  WHERE city = 'San Francisco' AND date = '2003-07-03'
  RETURNING temp_lo, temp_hi, prcp;

UPDATE

UPDATE accounts SET
  contact_first_name = (
    SELECT first_name FROM salesmen WHERE salesmen.id = accounts.sales_id
  ),
  contact_last_name = (
    SELECT last_name  FROM salesmen WHERE salesmen.id = accounts.sales_id
  );

UPDATE accounts SET (contact_first_name, contact_last_name) =
    (SELECT first_name, last_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

DELETE

[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    [ USING using_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

DELETE FROM films;

TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

TRUNCATE TABLE films;

DELETE

DELETE FROM films WHERE kind <> 'Musical';

DELETE FROM tasks WHERE status = 'DONE' RETURNING *;

DELETE FROM films
  WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');

DELETE FROM films USING producers
  WHERE producer_id = producers.id AND producers.name = 'foo';
Алехин Владислав
E-mail: v.alehin@corp.mail.ru
Спасибо за внимание!