Евгений Колесников 2 years ago
parent
commit
2817b1fc89
4 changed files with 319 additions and 39 deletions
  1. 2 2
      articles/5_1_1_1_data_dictionary.md
  2. 292 13
      articles/sql_for_beginner.md
  3. 24 21
      articles/sql_import.md
  4. 1 3
      readme.md

+ 2 - 2
articles/5_1_1_1_data_dictionary.md

@@ -3,7 +3,7 @@
 </a></td><td style="width: 20%;">
 <a href="../readme.md">Содержание
 </a></td><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы в среде MySQL Workbench
+<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
 </a></td><tr></table>
 
 # Словарь данных
@@ -75,5 +75,5 @@ FK | TagId | INT | | | Ссылка на словарь **Теги клиент
 </a></td><td style="width: 20%;">
 <a href="../readme.md">Содержание
 </a></td><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы в среде MySQL Workbench
+<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
 </a></td><tr></table>

+ 292 - 13
articles/sql_for_beginner.md

@@ -1,5 +1,5 @@
 <table style="width: 100%;"><tr><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы в среде MySQL Workbench
+<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
 </a></td><td style="width: 20%;">
 <a href="../readme.md">Содержание
 </a></td><td style="width: 40%;">
@@ -8,8 +8,14 @@
 
 # Основы SQL (синтаксис MySQL)
 
+* [Определение. Группы операторов](#определение-группы-операторов)
+* [Data Manipulation Language (DML)](#data-manipulation-language-dml)
+* [Data Definition Language (DDL)](#data-definition-language-ddl)
+
 <!-- добавтить count и функции работы со временем (between) -->
 
+## Определение. Группы операторов
+
 **Structured Query Language (SQL)** — язык структурированных запросов, с помощью него пишутся специальные запросы (SQL инструкции) к базе данных с целью получения этих данных из базы и для манипулирования этими данными.
 
 С точки зрения реализации язык SQL представляет собой набор операторов, которые делятся на определенные группы и у каждой группы есть свое назначение. В сокращенном виде эти группы называются **DDL**, **DML**, **DCL** и **TCL**:
@@ -35,7 +41,9 @@
 
 * **Transaction Control Language (TCL)** – группа операторов для управления транзакциями. Транзакция – это команда или блок команд (инструкций), которые успешно завершаются как единое целое, при этом в базе данных все внесенные изменения фиксируются на постоянной основе или отменяются, т.е. все изменения, внесенные любой командой, входящей в транзакцию, будут отменены.
 
-## Базовый синтаксис SQL команды SELECT
+## Data Manipulation Language (DML)
+
+### Базовый синтаксис SQL команды SELECT
 
 Одна из основных функций SQL — получение данных из СУБД. Для построения всевозможных запросов к базе данных используется оператор **SELECT**. Он позволяет выполнять сложные проверки и обработку данных.
 
@@ -66,7 +74,7 @@ SELECT [DISTINCT | ALL] поля_таблиц
 * **DESC** — по убыванию
 * **LIMIT** используется для ограничения количества строк для вывода
 
-### SQL-псевдонимы
+#### SQL-псевдонимы
 
 Псевдонимы используются для представления столбцов или таблиц с именем отличным от оригинального. Это может быть полезно для улучшения читабельности имён и создания более короткого наименования столбца или таблицы.
 
@@ -81,7 +89,7 @@ FROM
     GoodTypes;
 ```
 
-### Примеры использования
+#### Примеры использования
 
 Вы можете выводить любые строки и числа (литералы) вместо столбцов:
 
@@ -119,7 +127,7 @@ FROM
 
 >Поле **status** подсвечивается как зарезервированное слово SQL - экранируем его обратными кавычками.
 
-### Distinct - выбор уникальных значений
+#### Distinct - выбор уникальных значений
 
 Иногда возникают ситуации, в которых нужно получить только уникальные записи. Для этого вы можете использовать **DISTINCT**. Например, выведем список городов без повторений, в которые летали самолеты:
 
@@ -132,7 +140,7 @@ FROM
 
 Эта конструкция используется для формирования словарей, примеры рассмотрим в главе про команду **INSERT**
 
-### Условный оператор WHERE
+#### Условный оператор WHERE
 
 Ситуация, когда требуется сделать выборку по определенному условию, встречается очень часто. Для этого в операторе **SELECT** существует параметр **WHERE**, после которого следует условие для ограничения строк. Если запись удовлетворяет этому условию, то попадает в результат, иначе отбрасывается.
 
@@ -270,7 +278,7 @@ WHERE
     plane = 'Boeing' AND NOT townFrom = 'London';
 ```
 
-### Выборка сводных данных (из двух и более таблиц)
+#### Выборка сводных данных (из двух и более таблиц)
 
 При формировании сводной выборки данные беруться из нескольких таблиц. В операторе **FROM** исходные таблицы перечисляются через запятую. Также им могут быть присвоены алиасы. Синтаксис запроса выглядит следующийм образом:
 
@@ -329,7 +337,7 @@ id | name  | phone
 
 >Сводные выборки нам понадобятся при импорте данных в базу. Сначала вы выделяете из таблиц импорта словари. А потом из таблиц импорта и словарей формируете запрос `INSERT ... SELECT` для записи данных в основную таблицу.
 
-### Вложенные SQL запросы
+#### Вложенные SQL запросы
 
 Вложенный запрос — это запрос на выборку, который используется внутри инструкции SELECT, INSERT, UPDATE или DELETE или внутри другого вложенного запроса. Подзапрос может быть использован везде, где разрешены выражения.
 
@@ -470,7 +478,7 @@ SELECT поля_таблицы_1
 
 Вложенные подзапросы обрабатываются «снизу вверх». То есть сначала обрабатывается вложенный запрос самого нижнего уровня. Далее значения, полученные по результату его выполнения, передаются и используются при реализации подзапроса более высокого уровня и т.д.
 
-## Добавление данных, оператор INSERT
+### Добавление данных, оператор INSERT
 
 Для добавления новых записей в таблицу предназначен оператор **INSERT**.
 
@@ -509,7 +517,7 @@ INSERT INTO Goods
         `type` = 2;
 ```
 
-### Первичный ключ при добавлении новой записи
+#### Первичный ключ при добавлении новой записи
 
 Следует помнить, что первичный ключ таблицы является уникальным значением и добавление уже существующего значения приведет к ошибке.
 
@@ -537,7 +545,7 @@ INSERT INTO Goods
     VALUES (NULL, 'Table', 2);
 ```
 
-## Редактирование данных, команда UPDATE
+### Редактирование данных, команда UPDATE
 
 Команда **UPDATE** применяется для обновления уже имеющихся строк. Она имеет следующий формальный синтаксис:
 
@@ -587,7 +595,7 @@ UPDATE Products
     WHERE Manufacturer = 'Huawei';
 ```    
 
-## Удаление данных, команда DELETE
+### Удаление данных, команда DELETE
 
 Команда **DELETE** удаляет данные из БД. Она имеет следующий формальный синтаксис:
 
@@ -740,8 +748,279 @@ DELETE FROM Products;
     ```
 -->
 
+## Data Definition Language (DDL)
+
+**Data Definition Language (DDL)** – это группа операторов **определения** данных. Другими словами, с помощью операторов, входящих в эту группы, мы определяем структуру базы данных и работаем с объектами этой базы, т.е. создаем, изменяем и удаляем их.
+
+В эту группу входят следующие операторы:
+
+* CREATE – используется для создания объектов базы данных;
+* ALTER – используется для изменения объектов базы данных;
+* DROP – используется для удаления объектов базы данных.
+
+>В MySQL регистронезависимый синтаксис, ключевые слова дальше написаны КАПСОМ только для читабельности.
+
+### CREATE DATABASE - создание базы данных
+
+```sql
+CREATE DATABASE [IF NOT EXISTS] db_name
+```
+
+Оператор `CREATE DATABASE` создает базу данных с указанным именем. Если база данных уже существует и не указан ключевой параметр `IF NOT EXISTS`, то возникает ошибка выполнения команды.
+
+Если в названии базы данных присутствуют пробелы или название совпадает с ключевым словом SQL, то название можно экранировать символами обратной кавычки (подобное экранирование применяется и к названиям других сущностей): 
+
+```
+CREATE DATABASE `database` 
+```
+
+### DROP DATABASE - удаление базы данных
+
+```
+DROP DATABASE [IF EXISTS] db_name
+```
+
+Оператор `DROP DATABASE` удаляет все таблицы в указанной базе данных (строго говоря не только таблицы, а все имеющиеся объекты) и саму базу.
+
+### CREATE TABLE - создание таблицы
+
+```
+CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
+[table_options]
+```
+
+* `TEMPORARY` - Будет создана временная таблица. Временная таблица автоматически удаляется по завершении соединения, а её имя действительно только в течение данного соединения. Это означает, что в двух разных соединениях могут использоваться временные таблицы с одинаковыми именами без конфликта друг с другом или с существующей таблицей с тем же именем (существующая таблица скрыта, пока не удалена временная таблица).
+
+* `tbl_name` - Название таблицы.
+
+    Имя таблицы может быть указано как `db_name.tbl_name`. Эта форма записи работает независимо от того, является ли указанная база данных текущей.
+
+* `(create_definition, ...)` описывает набор создаваемых сущностей (столбцы, индексы и т.д.):
+
+    * колонка (столбец)
+
+        синтаксис:
+
+        ```
+        col_name col_type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
+            [PRIMARY KEY]
+        ```
+
+        * `col_name` - название;
+
+        * `col_type` - тип данных;
+
+            * TINYINT[(length)] [UNSIGNED] [ZEROFILL]
+            * INT[(length)] [UNSIGNED] [ZEROFILL]
+            * INTEGER[(length)] [UNSIGNED] [ZEROFILL]
+            * DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
+            * FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
+            * DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
+            * CHAR(length) [BINARY]
+            * VARCHAR(length) [BINARY]
+            * DATE
+            * TIME
+            * TIMESTAMP
+            * DATETIME
+            * TEXT
+            * ENUM(value1,value2,value3,...)
+            * SET(value1,value2,value3,...)
+
+        * `NOT NULL | NULL` - обязательность (по-умолчанию `NULL`);
+
+        * `DEFAULT default_value` - значение по-умолчанию;
+
+        * `AUTO_INCREMENT` - целочисленный столбец может иметь дополнительный атрибут AUTO_INCREMENT. При записи величины NULL (рекомендуется) или 0 в столбец AUTO_INCREMENT данный столбец устанавливается в значение `value+1`, где `value` представляет собой наибольшее для этого столбца значение в таблице на момент записи. Последовательность AUTO_INCREMENT начинается с `1`.
+
+        * `PRIMARY KEY` - представляет собой уникальный ключ KEY (KEY является синонимом для INDEX). Столбец с данным ключом должен быть определен как `NOT NULL`. В MySQL этот ключ называется PRIMARY (первичный). Таблица может иметь только один первичный ключ PRIMARY KEY (То есть если мы хотим создать составной первичный ключ, то надо создавать его отдельной сущностью). 
+
+        например:
+
+        ```sql
+        CREATE TABLE `test` (
+            `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
+        )
+        ```
+
+    * первичный ключ (подразумевается составной, хотя никто не мешает использовать и одну колонку) 
+    
+        синтаксис:
+
+        ```
+        PRIMARY KEY (index_col_name,...)
+        ```
+
+        Например, аналог предыдущего запроса
+
+        ```sql
+        CREATE TABLE `test` (
+            `id` int(11) NOT NULL AUTO_INCREMENT,
+            PRIMARY KEY (`id`)
+        )
+        ```
+
+    * индекс
+    
+        синтаксис:
+
+        ```
+        KEY [index_name] (index_col_name,...)
+        ```
+
+        или
+
+        ```
+        INDEX [index_name] (index_col_name,...)
+        ```
+
+        или   
+        
+        ```
+        UNIQUE [INDEX] [index_name] (index_col_name,...)
+        ```
+
+        * `index_name` - название индекса
+
+        * `index_col_name` - название колонки, входящей в ключ индекса: `col_name [(length)]`. Содержимое колонки может быть обрезано по длине `length` 
+
+        Ключ `UNIQUE` может иметь только различающиеся значения. При попытке добавить новую строку с ключом, совпадающим с существующей строкой, возникает ошибка выполнения команды.
+
+    * внешний ключ
+
+        синтаксис:
+
+        ```
+        [CONSTRAINT index_name] FOREIGN KEY (index_col_name,...)
+            REFERENCES главная_таблица (столбец_главной_таблицы,...)
+            [ON DELETE reference_option]
+            [ON UPDATE reference_option]
+        ```
+
+        * `(index_col_name,...)` - список полей, являющихся частью составного ключа (чаще всего просто одно поле). Должен соответствовать списку полей главной таблицы в выражении `REFERENCES`.
+        * `главная_таблица` - название таблицы, с которой устанавливается связь
+        * `(столбец_главной_таблицы,...)` - поля главной таблицы, по которым устанавливается связь
+
+        Внешние ключи позволяют установить связи между таблицами. Внешний ключ устанавливается для столбцов из зависимой, подчиненной таблицы, и указывает на один из столбцов из главной таблицы. Как правило, внешний ключ указывает на первичный ключ из связанной главной таблицы.
+
+        Для создания ограничения внешнего ключа после `FOREIGN KEY` указывается столбец таблицы, который будет представляет внешний ключ. А после ключевого слова `REFERENCES` указывается имя связанной таблицы, а затем в скобках имя связанного столбца, на который будет указывать внешний ключ.
+
+        С помощью выражений `ON DELETE` и `ON UPDATE` можно установить действия, которые выполняются соответственно при удалении и изменении связанной строки из главной таблицы. В качестве действия могут использоваться следующие опции:
+
+        * `CASCADE`: автоматически удаляет или изменяет строки из зависимой таблицы при удалении или изменении связанных строк в главной таблице.
+
+        * `SET NULL`: при удалении или обновлении связанной строки из главной таблицы устанавливает для столбца внешнего ключа значение NULL. (В этом случае столбец внешнего ключа должен поддерживать установку NULL)
+
+        * `RESTRICT`: отклоняет удаление или изменение строк в главной таблице при наличии связанных строк в зависимой таблице.
+
+        * `NO ACTION`: то же самое, что и `RESTRICT` - действие по-умолчанию.
+
+        * `SET DEFAULT`: при удалении связанной строки из главной таблицы устанавливает для столбца внешнего ключа значение по умолчанию, которое задается с помощью атрибуты DEFAULT. Несмотря на то, что данная опция в принципе доступна, однако движок InnoDB не поддерживает данное выражение.
+
+        Например:
+
+        ```sql
+        -- таблица "склад"
+        CREATE TABLE `warehouse` (
+            `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+            `title` varchar(100) DEFAULT NULL,
+            `quantity` int(11) DEFAULT NULL,
+        )
+
+        -- таблица "продажи"
+        CREATE TABLE `sales` (
+            `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+            `warehouse_id` int(11) DEFAULT NULL,
+            `quantity` int(11) DEFAULT NULL,
+            CONSTRAINT `sales_FK` 
+                FOREIGN KEY (`warehouse_id`) 
+                REFERENCES `warehouse` (`id`)
+        )
+        ```
+
+* `table_options` - тут можно настроить тип таблицы, кодировку символов, параметры автоинкремента. Но обычно эти параметры не трогают и они наследуются от аналогичных параметров базы данных.
+
+### ALTER TABLE - изменение структуры таблицы
+
+```
+ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
+```
+
+Оператор `ALTER TABLE` обеспечивает возможность изменять структуру существующей таблицы. Например, можно добавлять или удалять столбцы, создавать или уничтожать индексы или переименовывать столбцы либо саму таблицу.
+
+Оператор `ALTER TABLE` во время работы создает временную копию исходной таблицы. Требуемое изменение выполняется на копии, затем исходная таблица удаляется, а новая переименовывается. Так делается для того, чтобы в новую таблицу автоматически попадали все обновления кроме неудавшихся. 
+
+* Опция `IGNORE` управляет работой `ALTER TABLE` при наличии дубликатов уникальных ключей в новой таблице. Если опция `IGNORE` не задана, то для данной копии процесс прерывается и происходит откат назад. Если `IGNORE` указывается, тогда для строк с дубликатами уникальных ключей остается только первая строка, а остальные удаляются.
+
+* `alter_spec` - что меняется
+
+    * добавление новой колонки
+    
+        ```
+        ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
+        ```
+
+        В `create_definition` используется тот же синтаксис, что и при создании таблицы.
+
+        По-умолчанию столбец добавляется в конец списка столбцов, но с помощью модификаторов `FIRST` и  `AFTER` можно разместить столбец в начале списка или после какого-то имеющегося столбца.
+
+    * добавление первичного ключа
+    
+        ```
+        ADD PRIMARY KEY (index_col_name,...)
+        ```
+
+    * добавление внешнего ключа
+
+        ```
+        ADD [CONSTRAINT symbol] FOREIGN KEY (index_col_name,...)
+            REFERENCES главная_таблица (столбец_главной_таблицы,...)
+            [ON DELETE reference_option]
+            [ON UPDATE reference_option]    
+        ```
+
+        Например:
+
+        ```sql
+        -- добавление внешнего ключа в таблицу "продажи"
+        ALTER TABLE `sales`
+            ADD CONSTRAINT `sales_FK` 
+            FOREIGN KEY (`warehouse_id`) 
+            REFERENCES `warehouse` (`id`);
+        ```
+
+    * изменение существующей колонки
+
+        ```
+        ALTER [COLUMN] col_name [create_definition] {SET DEFAULT literal | DROP DEFAULT}    
+        ```
+
+        В целом параметры те же что и при создании, единствено отличается синтаксис добавления или удаления значения по-умолчанию.
+
+    * удаление колонки
+    
+        ```
+        DROP [COLUMN] col_name
+        ```
+
+    * удаление первичного ключа
+    
+        ```
+        DROP PRIMARY KEY
+        ```
+    * удаление индекса (в том числе внешнего ключа)
+    
+        ```
+        DROP INDEX index_name
+        ```
+
+---
+
+## Задание
+
+Написать скрипт, создающий базу данных по ERD вашего курсового проекта.
+
 <table style="width: 100%;"><tr><td style="width: 40%;">
-<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы в среде MySQL Workbench
+<a href="../articles/5_1_1_1_erd_workbench.md">Создание ER-диаграммы
 </a></td><td style="width: 20%;">
 <a href="../readme.md">Содержание
 </a></td><td style="width: 40%;">

+ 24 - 21
articles/sql_import.md

@@ -8,6 +8,9 @@
 
 # Восстановление базы данных из скрипта. 
 
+* [Подключение к базе данных (MySQL)](#подключение-к-базе-данных-mysql)
+* [Импорт данных](#импорт-данных)
+
 >Мы получаем скрипты для генерации структуры БД либо в задании на демо-экзамене, либо формируем из ER-диаграммы. Создание самой БД мы не рассматриваем (ни на демо-экзамене, ни на моем сервере у вас нет на это прав), но там ничего сложного и при желании вы можете установить локальную БД дома и с ней делать что угодно.
 
 ## Подключение к базе данных (MySQL)
@@ -81,7 +84,7 @@
 
 ![Выбор типа БД](../img/dbeaver02.png)
 
-В настройках соединения указываем доменное имя или IP сервера, название базы данных и имя пользователя (выдаст преподаватель или сами знаете какие в вашей БД), пароль.
+В настройках соединения указываем доменное имя (**kolei.ru**) или IP сервера, название базы данных (не обязательно), имя пользователя (выдаст преподаватель или сами знаете какие в вашей БД) и пароль (необязательно, но тогда придётся вводить при каждом подключении).
 
 Затем нажимаете **тест соединения** и, если всё введено правильно, и соединение устанавливается то жмёте **Готово**
 
@@ -91,33 +94,33 @@
 
 ![Список соединений](../img/dbeaver05.png)
 
-# Импорт данных.
+## Импорт данных.
 
 Стандартом *де-факто* для импорта/экспорта данных является формат CSV.
 
-## Что такое CSV-файлы
+### Что такое CSV-файлы
 
-Формат CSV используют, чтобы хранить таблицы в текстовых файлах. Данные очень часто упаковывают именно в таблицы, поэтому CSV-файлы очень популярны.
+Формат **CSV** используют, чтобы хранить таблицы в текстовых файлах. Данные очень часто упаковывают именно в таблицы, поэтому **CSV**-файлы очень популярны.
 
-CSV расшифровывается как comma-separated values — «значения, разделенные запятыми». Но разделителями столбцов в CSV-файле могут служить и точки с запятой, и знаки табуляции. Это все равно будет CSV-файл.
+**CSV** расшифровывается как *comma-separated values* — «значения, разделенные запятыми». Но разделителями столбцов в **CSV**-файле могут служить и точки с запятой, и знаки табуляции. Это все равно будет **CSV**-файл.
 
-У CSV куча плюсов перед тем же форматом Excel: текстовые файлы просты как пуговица, открываются быстро, читаются на любом устройстве и в любой среде без дополнительных инструментов.
**CSV** куча плюсов перед тем же форматом **Excel**: текстовые файлы просты как пуговица, открываются быстро, читаются на любом устройстве и в любой среде без дополнительных инструментов.
 
-Из-за своих преимуществ CSV — сверхпопулярный формат обмена данными, хотя ему уже лет 40. CSV используют прикладные промышленные программы, в него выгружают данные из баз.
+Из-за своих преимуществ **CSV** — сверхпопулярный формат обмена данными, хотя ему уже лет 40. **CSV** используют прикладные промышленные программы, в него выгружают данные из баз.
 
-Одна беда — текстового редактора для работы с CSV мало. Еще ничего, если таблица простая: в первом поле ID одной длины, во втором дата одного формата, а в третьем какой-нибудь адрес. Но когда поля разной длины и их больше трех, начинаются мучения.
+Одна беда — текстового редактора для работы с **CSV** мало. Еще ничего, если таблица простая: в первом поле ID одной длины, во втором дата одного формата, а в третьем какой-нибудь адрес. Но когда поля разной длины и их больше трех, начинаются мучения.
 
 Еще хуже с анализом данных — попробуй «Блокнотом» хотя бы сложить все числа в столбце. Я уж не говорю о красивых графиках.
 
-Поэтому CSV-файлы анализируют и редактируют в Excel и аналогах: Open Office, LibreOffice и прочих.
+Поэтому **CSV**-файлы анализируют и редактируют в **Excel** и аналогах: **Open Office**, **LibreOffice** и прочих.
 
-## Как Excel портит данные: из классики
+### Как Excel портит данные: из классики
 
-Все бы ничего, но Excel, едва открыв CSV-файл, начинает свои лукавые выкрутасы. Он без спроса меняет данные так, что те приходят в негодность. Причем делает это совершенно незаметно. Из-за этого в свое время мы схватили ворох проблем.
+Все бы ничего, но **Excel**, едва открыв **CSV**-файл, начинает свои лукавые выкрутасы. Он без спроса меняет данные так, что те приходят в негодность. Причем делает это совершенно незаметно. Из-за этого в свое время мы схватили ворох проблем.
 
 Большинство казусов связано с тем, что программа без спроса преобразует строки с набором цифр в числа.
 
-**Округляет**. Например, в исходной ячейке два телефона хранятся через запятую без пробелов: «5235834,5235835». Что сделает Excel? Лихо превратит номера́ в одно число и округлит до двух цифр после запятой: «5235834,52». Так мы потеряем второй телефон.
+**Округляет**. Например, в исходной ячейке два телефона хранятся через запятую без пробелов: «5235834,5235835». Что сделает **Excel**? Лихо превратит номера́ в одно число и округлит до двух цифр после запятой: «5235834,52». Так мы потеряем второй телефон.
 
 **Приводит к экспоненциальной форме**. Excel заботливо преобразует «123456789012345» в число «1,2E+15». Исходное значение потеряем напрочь.
 
@@ -129,18 +132,18 @@ CSV расшифровывается как comma-separated values — «зна
 
 **Разбивает по три цифры**. Цифровую строку длиннее трех символов Excel, добрая душа, аккуратно разберет. Например, «8 495 5235834» превратит в «84 955 235 834».
 
-Форматирование важно как минимум для телефонных номеров: пробелы отделяют коды страны и города от остального номера и друг от друга. Excel запросто нарушает правильное членение телефона.
+Форматирование важно как минимум для телефонных номеров: пробелы отделяют коды страны и города от остального номера и друг от друга. **Excel** запросто нарушает правильное членение телефона.
 
-**Удаляет лидирующие нули**. Строку «00523446» Excel превратит в «523446».
+**Удаляет лидирующие нули**. Строку «00523446» **Excel** превратит в «523446».
 А в ИНН, например, первые две цифры — это код региона. Для Республики Алтай он начинается с нуля — «04». Без нуля смысл номера исказится, а проверку формата ИНН вообще не пройдет.
 
-**Меняет даты под локальные настройки**. Excel с удовольствием исправит номер дома «1/2» на «01.фев». Потому что Windows подсказал, что в таком виде вам удобнее считывать даты.
+**Меняет даты под локальные настройки**. **Excel** с удовольствием исправит номер дома «1/2» на «01.фев». Потому что Windows подсказал, что в таком виде вам удобнее считывать даты.
 
-## Побеждаем порчу данных правильным импортом
+### Побеждаем порчу данных правильным импортом
 
-Если серьезно, в бедах виноват не Excel целиком, а неочевидный способ импорта данных в программу.
+Если серьезно, в бедах виноват не **Excel** целиком, а неочевидный способ импорта данных в программу.
 
-По умолчанию Excel применяет к данным в загруженном CSV-файле тип «General» — общий. Из-за него программа распознает цифровые строки как числа. Такой порядок можно победить, используя встроенный инструмент импорта.
+По умолчанию **Excel** применяет к данным в загруженном **CSV**-файле тип «General» — общий. Из-за него программа распознает цифровые строки как числа. Такой порядок можно победить, используя встроенный инструмент импорта.
 
 **Запускаем** встроенный в Excel механизм импорта.
 
@@ -161,11 +164,11 @@ CSV расшифровывается как comma-separated values — «зна
 * выбираем в контекстном меню «Format Cells»;
 * в открывшемся диалоге выбираем слева тип данных «Text».
 
-## Разбор импорта данных на примере прошлогоднего демо-экзамена
+### Разбор импорта данных на примере прошлогоднего демо-экзамена
 
 >Файлы, используемые в этом разборе, лежат в каталоге [data](/data) этого репозитория (`variant1.zip` и `variant2.zip`)
 
-### Создание таблиц из скрипта
+#### Создание таблиц из скрипта
 
 1. Откройте [соединение](#подключение-к-базе-данных) с БД
 
@@ -183,7 +186,7 @@ CSV расшифровывается как comma-separated values — «зна
 
     ![](../img/01032.png)
 
-### Импорт данных
+#### Импорт данных
 
 В ресурсах у нас есть три файла для импорта:
 

+ 1 - 3
readme.md

@@ -196,12 +196,10 @@ http://sergeyteplyakov.blogspot.com/2014/01/microsoft-fakes-state-verification.h
 
 1. [Словарь данных](articles/5_1_1_1_data_dictionary.md)
 
-1. [Создание ER-диаграммы в среде MySQL Workbench](articles/5_1_1_1_erd_workbench.md)
+1. [Создание ER-диаграммы](articles/5_1_1_1_erd_workbench.md)
 
 1. [Основы SQL](./articles/sql_for_beginner.md)
 
-1. [DDL](./articles/ddl.md)
-
 1. [Создание базы данных. Импорт данных.](./articles/sql_import.md)
 
 1. [Импорт данных (вариант 22).](./articles/sql_import_22.md)