27. C-sharp 23 18-02-2014

Created Tuesday 18 February 2014

  1. Теория нормализации баз данных
    1. Как делить таблицы на другие таблици и как их соединять
    2. Как выполнять запросы к нескольким таблицам
    3. Ключи
    4. Индексы
  2. Нормализация
    1. Относится только к реляционным базам данных
    2. Как находить в базе данных более одной таблицы
    3. Как находить несколько таблиц, которые относятся к одной
  3. Теория нормализации обоснованна Эдгаром Коддом
    1. 50 "правил" Кодда
    2. Из них необходимо знать 12 (т.н. 12 "заповедей" Кодда)
    3. Это тоже было сложно, поэтому всё свелось к 5 правилам нормализации
      1. Вложенные: если выполнено 1-е, то выполняется 2-е, если выполнено 2-е, то 3-е и т.д.
      2. Если выполнено хотя бы 3 первых правила, то база данных считается достаточно хорошей с точки зрения нормализации
    4. 5 правил нормальной формы:
      1. Преимущества:
        1. Предотвращение противоречивости
        2. Предотвращение избыточности
        3. Декомпозиция — разбиение большого количества столбцов на более адекватные таблицы
      2. Правила (нормальные формы):
        1. 1NF
          1. В каждой таблице должно быть хотя бы одно поле (столбец), которое однозначно идентифицирует любую запись (ключ)
        2. 2NF
          1. 1-е правило выполнено. Значение любого поля таблицы должно зависеть только от ключа, в противном случае ей место в отдельной таблице
        3. 3NF
          1. ... Читать всё это онлайн (Вики)
  4. Если в таблице в определённом столбце есть много повторений, то во избежание избыточности лучше выделить для этого столбца отдельную таблицу (декомпозиция)
  5. Каждая строка таблицы должна описывать объект. Если есть поля, по смыслу не относящиеся к объекту таблицы, то имеет смысл попробовать создать для них отдельную таблицу.
  6. insert into table2 select * from table1; — перенести данные из одной таблицы в другую с подходящей структурой; * можно (нужно) заменить именами полей:
    1. insert into tabe2 ([field1], [field2]) select [field3], [field4] from table1;
  7. Выбор из нескольких таблиц:
    1. select table1.id, table2.title from table1, table2
    2. select p.id, p.title, c.title, p.price from table1 as p, table2 as c where c.id=1; — создаст декартово произведение, лучше:
    3. select p.id, p.title, c.title, p.price from table1 as p, table2 as c where p.category_id=c.id and c.id=1;
    4. select p.id, p.title, c.title, p.price from table1 as p inner join table2 as c on where c.id=1;
    5. select p.id, p.title, c.title, p.price from table1 as p left outer join table2 as c on p.category_id=c.id — отобразить даже пустые (NULL) в дочерней таблице, даже если нет совпадений в родительской
  8. Записи в подчинённой таблице, не связанные с родительской называются сиротами — недопустимое явление
    1. select p.id, p.title, c.title, p.price from table1 as p right outer join table2 as c on p.category_id=c.id — способ найти сирот
  9. При правильно спланированной структуре базы данных не должно быть необходимости в выборке из более, чем 3-х таблиц (это ещё и медленно)
  10. 1 ко многим (родитель — ребёнок) это частое явление
  11. Многие ко многим — когда каждой записи в одной таблице соответствуют несколько в другой и наоборот
    1. Нужно завести специальную (служебную) таблицу, где будут два столбца-идентификатора, скажем, ID продукта и ID категории (foreign keys — помимо первичного ключа) — эта таблица будет выполнять функцию референса между продуктом и категорией (в примере Iphone может быть и телефоном, и компьютером)
  12. Первичный ключ упорядочивает записи, и если в таблицу есть много insert-ов, то, возможно, имеет смысл завести отдельную таблицу для insert-ов и отдельную — для select-ов
  13. Первичный ключ приводит к индексации записей таблице по нему.
  14. Первичный ключ является так называемым кластерным индексом — все записи отсортированы по нему. Кластерным индексом может быть только один.
  15. Индекси и их использование при проектировании таблиц
    1. Constraint — специальный ограничитель в базе данных
    2. Можно приказать системе поддерживать индекс для любого поля:
      1. Система создаёт в оперативной памяти коллекцию в отсортированном порядке
      2. При добавлении insert-ом записи в таблицу она всегда добавляется в конце, но поскольку по этому полю всегда существует индекс, система идёт в индекс и вставляет эту запись в индексе туда, куда нужно, и в отдельном столбце ставится ссылка на "физическое" расположение в реальной таблице
      3. Все поля, которые используются в where, нужно анализировать на то, чтобы они были проиндексированы — в идеале любое поле, использующееся в where должно быть проиндексровано
    3. Индексация больших таблиц занимает много времени, поэтому ещё при проектировании и тестировании запросов к таблице следует спроектировать индексацию
    4. Покрытие индекса — все поля, используемые в where, имеют индекс. Например, неполное покрытие — когда есть неиндексируемые поля, используемые в where
    5. Использование очень многих полей в where — признак неправильно спроектированной базы
    6. Единственный случай, когда не нужно индексов — отдельная таблица для insert-ов
  16. Если медленно работает база:
    1. Оптимизация запроса (какой индекс добавить)
    2. Индексация
  17. Новый учебник (Data access solutions):
    1. Модуль 14
      1. ADO.NET
        1. Базовый набор классов для работы с базами данных:
          1. DbConnection — соединение с базой данных
            1. Всегда следует проверять соединение с базой (чем раньше — тем лучше)
            2. Соединение с базой данных описывается при помощи текстовой строки, в которой записаны параметры соединения
              1. Connection string
                1. connectionstrings.com
            3. В Нотпад создать пустой файл с расширением .udl
              1. Двойной щелчок мыши по файлу приведёт к открытию окна соединения с базой данных
              2. Провайдер — это некий программный модуль, который точно знает, как устроена база данных — выбрать наиболее близкий по названию к базе провайдер
              3. Выбрать сервер и базу и нажать Test Connection
              4. Открыть файл в Нотпад — там будет сгенерирован Connection string
              5. Открыть Visual Studio проект и убедиться, что в References есть System.Data
              6. System.Data.OleDb.OleDbConnection conn1 = new System.Data.OleDb.OleDbConnection(@"...Generated connection string...");
              7. conn1.Open();
              8. string sql_query = "...some sql query...";
              9. System.Data.OleDb.OleDbCommand comm = new System.Data.OleDbCommand(sql_query, conn1);
              10. System.Data.OleDb.OleDbDataReader reader = comm.ExecuteReader();
              11. while (reader.Reader()) { // Каждый цикл даёт доступ к очередной записи
              12. int id = reader.GetInt32(0); // 0, 1 — номера столбцов
              13. string title = reader.GetString(1);
              14. decimal price = reader........
              15. Console.WriteLine("{0} {1}", id, title);
              16. } // Reader — самый быстрый способ прочитать данные из базы
              17. conn1.Close(); // Or use "using"...
          2. DbCommand — см. выше использование
          3. ExecuteReader — выполнить команду
          4. SqlDataReader — класс, при помощи которого можно перебирать полученные записи
  18. Литература:
    1. Дейт
  19. ДЗ: Модуль 14 по новому учебнику, практиковать пройденное на уроке



Backlinks: