Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Новости сайта "Упражнения по SQL" (http://www.sql-ex.ru) 97


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)" Выпуск 97 (22 июля 2006 г.)

http://www.sql-ex.ru

Новым посетителям сайта

Сайт посвящен изучению языка, с помощью которого осуществляется взаимодействие с реляционными (и не только) СУБД. Суть обучения состоит в выполнении заданий на написание запросов к учебным базам данных; при этом система контролирует правильность выполнения заданий. В настоящее время реализованы все операторы подъязыка манипуляции данными (DML), которые включают в себя оператор извлечения данных SELECT, а также операторы модификации данных - INSERT, DELETE и UPDATE.

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

Демонстрация плана выполнения запроса и сравнительная оценка эффективности решений поможет вам освоить принципы оптимизации запросов.

Имеется возможность получить сертификат по SQL DML при выполнении определенного количества заданий.


Новости сайта

§ Подлатал проверку задачи 93. Прохождение неверных решений заметил Roman S. Golubin.

§ Дособирал отзывы о проекте. Получилось 2 странички.
Мне бы хотелось, чтобы все отзывы были подписаны, но некоторые из них я брал с форума SQL.RU, а у некоторых моих респондентов устарел почтовый ящик. Обращаюсь с просьбой к тем, кто увидит свой отзыв на этих двух страничках, сообщить информацию о себе, естественно, если вы не против публикации.
Я старался собрать все отзывы, в которых проявлялась заинтересованность к ресурсу, а не только хвалебные. Некоторые предложения уже реализованы в той или иной мере, по некоторым замечаниям приняты исправительные меры.

§ Подрезал число аксакалов. Годы идут, и 365 дней уже не кажутся таким большим числом. Поставил 600. Напомню, что 600 - это число дней, которые прошли между первым и последним решенными упражнениями. Вторым критерием здесь является преодоление первого сертификационного порога, проще говоря, 65 задач на SELECT. Попасть в аксакалы не так и сложно, т.к. новые задачи добавляются регулярно.
Зато я увеличил список претендентов на попадание в ТОР 100. Теперь сюда входят те, кто решил минимум 66 задач на SELECT, причем последняя решенная задача датируется текущим или предыдущим месяцем.

§ Возвращение лидера. Победив 138 задачу и установив рекорд на 87-ой, на первое место вернулся paparome. Результат (задач 138, время 2.682) недостижим для ближайших преследователей.
Похоже, что интригу можно возродить только на третьем этапе, до которого пока руки не дошли. Впрочем, есть еще несколько новых задач в запасе, однако, большинство из них опять же принадлежит paparome :-).
На третье место переместился lepton (138, 10.102). Остальные лидеры или выжидают, или пока не решили 87 задачу.

§ Проверка английских формулировок закончена: a2010 принялся за последнюю 138 задачу. Мне думается, что он сможет ее решить. Возможно, что мы увидим его в десятке.
Кажется, соревнование приобретает международный статус :-).

§ Сохранили шансы попасть в ТОР 10:
ValdemarES (137, 7.807)
a2010 (137, 15.365)
=Maxim= (121, 11.802)
maxifly (115, 2.186)

§ Продолжили свое восхождение к вершине:
Phohack (135, 129.167)
SoVa (124, 94.307)
ba (122, 38.315)
FanOfBeer (120, 72.267)
T! (115, 36.418)
Johnny (114, 130.073)
Ocean (108, 27.741)

§ На этой неделе сертифицированы:
Оля (A06008771) [BK] (г.Элиста, Россия)
Roman S. Golubin (B06005936) [AR] (г.Северодвинск, Россия)
Platon (A06010718) [BK] (г.Ижевск, Россия)

§ Число подписчиков - 3205

Число участников рейтинга - 6655

Число участников второго этапа - 619

Сертифицировано на сайте - 79

Лучшие результаты (ТОР 20)

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 LastSolved LastVisit
1 >Войнов П.Е. (pаparome) 138 87 20 321 331 2.682 21 Jul 2006 21 Jul 2006
2 Юлдашев М.Р. (Snowbear) 138 87 20 321 361 4.038 14 Jul 2006 21 Jul 2006
3 Мурашкин И.В. (lepton) 138 87 20 321 118 10.102 19 Jul 2006 21 Jul 2006
4 Голубин Р.С. (Roman S. Golubin) 138 87 20 321 330 20.825 14 Jul 2006 21 Jul 2006
5 Кувалкин К.С. (Cyrilus) 137 138 20 318 484 5.444 23 Mar 2006 21 Jul 2006
6 Slobodcicov A.N. (Testo) 137 138 20 318 252 6.711 01 Jun 2006 18 Jul 2006
7 Kamaev V.M. (Heromantor) 137 138 20 318 128 9.060 14 Mar 2006 25 Mar 2006
8 Бураков С.Г. (burakov58) 137 138 20 318 419 17.384 24 Mar 2006 07 Apr 2006
9 Иванов А.Н. (Goapsy) 137 138 20 318 211 18.275 09 Jun 2006 09 Jun 2006
10 Тарасов Д.Б. (Gavrila) 137 138 20 318 208 19.398 22 Mar 2006 21 Jul 2006
11 Валуев Д.И. (Fiolent) 137 138 20 318 971 47.987 02 May 2006 21 Jul 2006
12 Самохвалов В. (ValdemarES) 137 87 20 317 244 7.807 19 Jul 2006 21 Jul 2006
13 frenkental (a2010) 137 137 20 317 110 15.365 19 Jul 2006 21 Jul 2006
14 Карасёва Н. (vlksm) 137 87 20 317 69 22.350 14 Jul 2006 21 Jul 2006
15 Зверев Д.Л. (dimzv) 136 137 20 314 869 3.274 22 Mar 2006 08 Jul 2006
16 Абашин П.И. (Dizil) 136 137 20 314 203 3.773 15 Mar 2006 04 Jul 2006
17 Носков Н.В. (niko2) 136 137 20 314 274 8.468 06 Apr 2006 16 May 2006
18 Крижевич С.А. (yaff) 136 137 20 314 259 14.797 16 Mar 2006 05 May 2006
19 Держальцев В.А. (MadVet) 136 137 20 314 357 18.631 08 Apr 2006 08 Jul 2006
20 Зырин В.Е. (Vezyr) 136 137 20 314 63 20.601 17 Mar 2006 20 Jul 2006

Лучшие результаты за неделю

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 >Васьков Е.В. (Johan) 54 54 98 19 117 560 21 Jul 2006
2 Semeshin A.N. (Semeshin) 54 54 98 11 109 641 20 Jul 2006
3 Колосков А.А. (троль) 41 41 74 17 91 956 21 Jul 2006
4 Ганюшкин (CaHeK) 46 46 79 9 88 994 21 Jul 2006
5 Шушунов (Kite) 27 66 52 29 81 253 20 Jul 2006
6 >Яманбаева А.Ф. (mirrka) 42 42 66 0 66 1448 21 Jul 2006
7 Аверьянов И. (Иван1983) 26 40 52 9 61 1219 20 Jul 2006
8 >Вязовецков А.С. (alex_v) 25 104 55 0 55 146 21 Jul 2006
9 >Чубенко А.С. (Angel_DSTU) 27 34 45 9 54 1609 21 Jul 2006
10 Popkov M.V. (maximo) 28 34 54 0 54 1630 19 Jul 2006
11 Шашкин А.В. (Freddie Mercury) 23 42 51 0 51 1214 17 Jul 2006
12 shtril I. (imsh) 22 86 49 0 49 160 21 Jul 2006
13 >Aghajanyan (Agma) 22 41 38 9 47 1271 21 Jul 2006
14 Raghavendra P. (prachandaprabhu) 26 30 47 0 47 1945 21 Jul 2006
15 >Пугина М.В. (marinap) 30 30 47 0 47 2099 21 Jul 2006
16 Andrei M.R. (3nder) 23 58 45 1 46 657 19 Jul 2006
17 Зубарев (Zevs) 18 36 31 15 46 1326 21 Jul 2006
18 >S (Feeria) 27 27 46 0 46 2134 21 Jul 2006
19 >Vassilchenko I.N. (phenix777) 32 32 44 0 44 2195 21 Jul 2006
20 >Efremov M.A. (max_ft) 22 28 43 0 43 1974 21 Jul 2006
21 Wu I. (10B) 27 27 41 0 41 2307 19 Jul 2006
22 Богданов А.А. (Alexey Danov) 4 64 7 32 39 281 17 Jul 2006
23 >Колпаков А. (АлександрI) 14 74 32 6 38 204 21 Jul 2006
24 >Lichota L. (Seeker) 25 25 37 1 38 2448 21 Jul 2006
25 Суслов Д.В. (Platon) 7 66 14 23 37 259 21 Jul 2006
26 Zhuk M. (^-_-^) 24 24 37 0 37 2495 17 Jul 2006
27 Видякин С.А. (Vidyakin S.A.) 24 24 37 0 37 2499 16 Jul 2006
28 Kovshun D. (AmiD) 11 25 25 11 36 1947 21 Jul 2006
29 Шевченко А.Л. (Alexander Shevchenko) 27 27 33 3 36 2628 18 Jul 2006
30 >Popa A. (Ane) 23 23 36 0 36 2634 21 Jul 2006
31 >Самсонов С.А. (SQS) 19 59 35 0 35 324 21 Jul 2006
32 Макаренко Н.А. (Flow) 17 48 33 0 33 1071 19 Jul 2006
33 >Ghenita D.V. (Doric) 19 25 32 0 32 2472 21 Jul 2006
34 >МОХОВ М.В. (cool_mouse) 18 18 23 9 32 2911 21 Jul 2006
35 Афанасова В.А. (veraa) 22 22 31 0 31 2992 21 Jul 2006
36 >v (PLV) 22 22 31 0 31 3018 21 Jul 2006
37 Zab (zeagle) 21 21 30 0 30 3080 17 Jul 2006

Изучаем SQL

Безумие справочных таблиц

Don Peterson (оригинал: Lookup Table Madness)
Перевод Моисеенко С.И.

Аннотация

Вы безумный? Не сердитый, а скорее сумасшедший, когда дело доходит до проектирования баз данных на SQL Server? Дон Петерсон встречал нескольких человек, которые, как он думает, именно таковы, когда дело доходит до построения поисковых таблиц. Проистекает ли это от плохого понимания проектирования базы данных? Или Вы не согласны? Прочитайте возражения Дона против такой методики проектирования.

За эти годы я участвовал во множестве "дискуссий" о практике создания обобщенных "поисковых" таблиц для хранения многочисленных типов кодов в единственной таблице. Я не буду держать вас в неизвестности относительно моего взгляда на эти методы, основа которых лежит в отказе от изучения и признания ценности фундаментальных принципов хорошего проектирования базы данных. Соответственно, я придумал подходящее название для таких таблиц: Массово унифицированные ключевые таблицы кодов (Massively Unified Code-Key tables ) или MUCK (переводится как НАВОЗ - прим. переводчика).

Давайте рассмотрим причины, почему некоторые люди испытывают желание использовать этот подход, но, что еще более важно, я надеюсь объяснить, почему Вам не следует его использовать. Многие "поисковые" таблицы выглядят примерно как эти примеры:

CREATE TABLE EmployeeStatusCode (
    EmployeeStatusCode int IDENTITY(1,1)
     , Description varchar(50))

CREATE TABLE CustomerStatusCode (
     CustomerStatusCode int IDENTITY(1,1)
     , Description varchar(50))

CREATE TABLE FacilityStatusCode (
     FacilityStatusCode int IDENTITY(1,1)
     , Description varchar(50))

* К слову, я не люблю термин "Поисковые" таблицы, ни любой из его синонимов (кодовая таблица - Code Table, доменная таблица - Domain Table, справочная таблица - Reference Table и т.д ...), т.к. он слишком неоднозначен, чтобы быть полезным. Как точно Вы их определите? Является ли это просто некоторая таблица, на которую есть ссылка по внешнему ключу? Очевидно, нет. А как насчет таблицы, на которую ссылается FK и которая не ссылается ни на какую другую таблицу? Нет... Даже при том, что я использую этот термин в данной статье, я хочу отметить, что эти таблицы существенно не отличаются от любых других таблиц в вашей базе данных и поэтому не должны иметь никакой специальной трактовки*

** Для ясности..., я не защищаю повсеместное использование столбцов IDENTITY (или вообще суррогатных ключей), т.к. эта тема требует намного более детального рассмотрения, чем я намереваюсь дать в этой статье. Я использую этот пример только потому, что он является очень распространенным. **

Поскольку коды состояния служащего (Employee), клиента (Customer) и средства (Facility) выглядят одинаково, утверждается, что с точки зрения "определенной перспективы" они имеют один и тот же тип и должны посему находиться в одной таблице. Это кажется не лишенным смысла до тех пор, пока Вы не поймете, что совместное использование ряда общих атрибутов - это только один из критериев, которые должны рассматриваться при определении таких вещей. К сожалению, эта "определенная перспектива", при которой ваши кодовые таблицы могут соответственно быть объединены, также делает их неэффективными для использования по их оригинальному назначению - обеспечению целостности данных. Даже поверхностная проверка должна сказать нам, что EmployeeStatusCode не ТО ЖЕ САМОЕ, что и CustomerStatusCode, независимо от того, насколько ПОДОБНЫ они по своему внешнему виду. Мы никогда бы не захотели, чтобы состояние клиента (Customer) было "Fired" (запущен) или состояние служащего - "Vacant" (свободен) независимо от того, насколько это описание может подходить для некоторых из них :-). Есть несколько альтернативных возможностей воспрепятствовать этому, но, как я покажу далее, каждая из них создает еще большие проблемы.

Как правило, во время процесса нормализации (нет, нормализация не является здесь грязным словом) эти коды удаляются из таблиц Employee, Customer и Facility и соответственно помещаются в их собственные таблицы. Затем некто обращает внимание на подобие кодовых таблиц и решает, что база данных будет более простой, если объединить их в единственную таблицу. Нормализация устраняет избыточность данных, значительно упрощая, тем самым, задачу поддержания целостности данных, но процесс создания MUCK никак не связан с целостностью. MUCK не устраняет избыточные данные, скорее они есть устранение того, что ВОСПРИНИМАЕТСЯ как избыточные таблицы, но, как я продемонстрирую, меньшее число таблиц не эквивалентно простоте.

Вы можете сказать: "Этот парень не знает того, о чем говорит! MUCK действительно помогает устранить избыточные данные в тех случаях, когда EmployeeStatusCode использует то же самое описание, что и CustomerStatusCode и так далее." Прекрасно, но это лишь послужит в дальнейшем иллюстрацией, почему Вы не должны трактовать эти коды как вещи одного и того же типа. Не требуется длительного размышления, чтобы понять, что эта логика быстро ведет нас обратно в уродливый мир аномалий обновления и другого нереляционного уродства. То есть. Что, если требования бизнеса приводят к изменению этого специфического описания, но только для служащих? Возможно это? Несомненно, но в чем проблема?

Как упомянуто выше, как только Вы получаемее MUCK, возникает проблема, говорящая: какие ограничения наложить на данные, чтобы гарантировать применимость кодов типа X исключительно к X? Первый вариант, о котором задумывается масса людей, - это триггеры. Добавьте столбец CodeType к MUCK и напишите соответствующие триггеры. Просто!..., но прежде чем остановиться на этом подходе, продолжим читать. Если Вы не хотите использовать триггеры для поддержания целостности, Вы могли бы попробовать включить столбец CodeType в таблицу Employee с ограничением на столбец, которое предотвращает любые коды состояния, которые не относятся к типу служащего.

Рассмотрим пример:

CREATE TABLE Code (
     CodeID int IDENTITY(1,1)
     , CodeType int
     , Description varchar(255))

ALTER TABLE Code ADD CONSTRAINT PK_Code PRIMARY KEY (CodeID, CodeType)

Очевидно, мы могли бы иметь таблицу CodeType ..., но с другой стороны, почему просто не впихнуть это в нашу таблицу Code? В конце концов, она выглядит точно так же, как все наши остальные коды! Есть место для каждого на борту этой рекурсивной поездки на американских горках!

Наша таблица Employee выглядела бы примерно так:

CREATE TABLE Employee (
     EmployeeID int IDENTITY(1,1)
     , FirstName varchar(50)
     , LastName varchar(50)
     , CodeType int
     , CodeID int
     , и т.д ...)
ALTER TABLE Employee ADD CONSTRAINT FK_Code FOREIGN KEY (CodeID, CodeType)
REFERENCES Code (CodeID, CodeType)

ALTER TABLE Employee ADD CONSTRAINT CHK_CodeType CHECK(CodeType = 1)

Это должно работать, правильно? Да, но при этом Вы должны пожелать не замечать слона в гостиной комнате, наша таблица служащих не нормализована должным образом, поскольку CodeID, в частности, зависит от CodeType, который не является частью ключа (и нет, Вы не можете просто сделать CodeType чатью ключа, потому что FirstName, LastName и т.д ... не зависели бы тогда от всего ключа). Теперь подумаем о том, какая образуется мешанина, если служащий может иметь более одной комбинации значений Code/CodeType. Далее, а что если одна из этого множества пар Code/CodeType зависит от другой пары? Прежде, чем Вы побежите назад в "простоту" варианта с триггерами, следует понять, что там имеется та же самая проблема, но она сокрыта в логике триггера и вероятно потребовала кода значительного размера. Фактически можно утверждать, что триггерный вариант является худшим выбором, потому что CodeID имеет функциональную зависимость от столбца, который там даже не находится! Картина становится только более уродливой, если Вы примете во внимание потери производительности на триггерах по сравнению с DRI (декларативная ссылочная целостность).

(Окончание следует...)

Полезная информация

§ Все статьи, публикуемые в рассылке, затем выкладываются на сайте Книги и статьи по SQL.

§ Поступила в продажу книга SQL. Задачи и решения, посвященная анализу ошибок, допускаемых при решении задач первого этапа. На сайте издательства Питер можно сделать заказ и познакомиться с содержанием.

Контакты

По всем вопросам, связанным с функционированием сайта, проблемами при решении упражнений, идеями вы можете обращаться к Сергею И.Моисеенко msi77@yandex.ru. Вы также можете предложить свои задачи для публикации на сайте.

Подписка Subscribe.Ru
Новости сайта "Упражнения по SQL"

В избранное