Структурированные и реляционные базы данных есть везде. Часто говорят, что веб-приложения представляют собой интерфейсные интерфейсы для серверной базы данных. В протоколе без сохранения состояния, таком как HTTP, ваша база данных сохраняет состояние и служит постоянным слоем. Это мозги за машиной.
В традиционном смысле шаблона проектирования MVC ваша модель данных решает проблему. То, как вы разрабатываете базу данных, напрямую связано с общим решением. Если вы в конечном итоге получите базу данных, полную запутанного раздувания и дублирования, ваш код переднего плана будет отражать именно это.
Итак, в этой статье я хотел бы взглянуть на базы данных SQL. Как оказалось, Rails делает это легко. Эта структура позволяет легко думать о реальных проблемах как о моделях данных и отношениях.
Отношения в вашей модели данных превращают модели в «объекты» реального мира. Удивительность в том, насколько хорошо она вписывается в парадигму ООП. Это упрощает основы кода и делает архитектуру понятной и гибкой.
Я надеюсь, что к концу этой статьи вы оцените структурированные и реляционные базы данных. Это поможет вам понять, почему ваше внутреннее структурированное хранилище имеет решающее значение для звуковой архитектуры.
И все мы хотим спроектировать красивую архитектуру, верно? Давайте начнем.
Настроить
Вы более чем можете следовать, если хотите. Я приведу код в конце этой статьи.
Чтобы начать, введите эту каноническую команду:
rails new understanding_sql_through_rails
Для этого конкретного примера это запуск системы проводки мельницы. Он состоит из пользователей, сообщений и категорий. Исходя из этого, мы определим отношения и разберемся с SQL.
Основное внимание здесь уделяется модели в шаблоне проектирования MVC.
Итак, наберите:
rails g model User name:string{30}
rails g model Post title:string{40} content:text{3200} user:references:index
rails g model Category name:string{15}
rails g migration CreateCategoriesPostsJoinTable categories:index posts:index
Рекомендуется устанавливать максимальные ограничения для ваших полей. В структурированной базе данных компьютеру будет намного проще индексировать данные при задании разумных размеров. Большим преимуществом структурированных наборов данных является то, что они занимают определенное количество места, поэтому их можно легко запрашивать. Я рекомендую использовать это в ваших интересах. (Примечание: это общее утверждение, которое применяется к большинству систем РСУБД, за исключением PostgreSQL, где длины полей не влияют на производительность .)
Теперь закончите с:
rake db:migrate
Легко. Rails полностью настроил мою модель данных для кирпича и строительного раствора. Вы можете исследовать ваши файлы миграции, чтобы увидеть, что генерируется под обложками. Что удивительно в этой среде, так это то, насколько просто настроить мою реляционную базу данных с помощью простых команд.
В завершение убедитесь, что в ваших моделях установлены правильные ассоциации.
В приложении / models / category.rb:
class Category < ActiveRecord::Base
has_and_belongs_to_many :posts
end
В приложении / models / post.rb:
class Post < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :categories
end
В приложении / models / user.rb
class User < ActiveRecord::Base
has_many :posts
end
Эти ассоциации встроены в Rails прямо из коробки. Обратите на это внимание и прочитайте их вслух. У пользователя много сообщений, например, сообщение принадлежит пользователю. Когда мы перейдем к уровню SQL, эти отношения будут иметь смысл.
Теперь поместите это в ваш db / seeds.rb:
user = User.create({name: 'Joe'})
post = Post.create({title: 'Post', content: 'Something', user_id: user.id})
Category.create({name: 'Cat1', post_ids: [post.id]})
Завершите это с:
rake db:seed
Закончено.
Отношения
С Rails вся ваша база данных настроена. Теперь пришло время углубиться в то, что только что произошло. Фреймворк хорошо абстрагируется. Увы, для нас пришло время выяснить, как все это работает.
Напечатать:
rails console
> post = Post.first
> post.categories
> category = Category.first
> category.posts
> user = User.first
> user.posts
Фреймворк запускает все виды SQL для вас, используя отношения. Как видите, пост имеет и относится ко многим категориям. Категории есть и принадлежат многим постам. У пользователя много постов.
Эти отношения очень интуитивны, так как вы можете говорить о них на обычном простом английском языке. Что в этом такого радикального, так это то, что вам даже не нужно ничего знать о технологии под прикрытием. Любой человек, который знает достаточно о проблеме, теперь свободно владеет моделью предметной области.
В любом решении модель предметной области составляет объекты и отношения из реального мира. Это среда, которую вы используете, чтобы общаться с вашими клиентами. Это облегчает общение с людьми, которым все равно, как вы решаете их проблему.
Клиент или человек, который заботится только о вашем конечном продукте, хорошо разбирается в этом. Клиент более чем счастлив соотнести проблему с точки зрения домена. Это означает, что вы, как архитектор, теперь можете связать проблему реального мира с компьютерной программой.
Излишне говорить, помните, что я сказал о том, как ваша модель решает проблему?
Каким-то образом в вашей базе данных SQL есть способ отслеживать эти отношения. Но остается вопрос, как?
SQL-запросы
На этот раз наберите:
rails dbconsole
Позвольте записи показать, что мы официально не в мире Rails и в SQL. SQLite должен быть базой данных по умолчанию.
Если мы хотим запросить сообщения, которые принадлежат пользователю с идентификатором один, попробуйте:
SELECT id, title FROM posts WHERE posts.user_id = 1;
Как показано, когда дочерний объект принадлежит родительскому объекту, дочерний объект получает внешний ключ, добавленный из родительского объекта.
Теперь для чего-то более сложного, скажем, я хочу посты, которые относятся к категории «Cat1»:
SELECT posts.id,
posts.title
FROM categories,
posts,
categories_posts
WHERE categories.id = categories_posts.category_id
AND posts.id = categories_posts.post_id
AND categories.name = 'Cat1';
Вот диаграмма того, как эти отношения выглядят:
Я использую неявные соединения. Это позволяет легко увидеть отношения внутри WHERE
В любом заданном объекте или таблице SQL id
Обратите внимание, как первичный ключ становится точкой опоры, на которой можно строить отношения. Компьютер всегда будет лучше обрабатывать цифры, поэтому первичные ключи — идеальное место для связи информации.
Я вижу SQL как простой язык запросов. Таким образом, в своей практике я использую его для простого запроса информации. Делать гораздо больше, чем это, означает помещать бизнес-логику в ваш SQL Я рекомендую вам избежать этого любой ценой. Ваша логика домена не принадлежит SQL.
На этой основе вы сможете эффективно использовать отношения SQL для уменьшения дублирования данных. Каждый раз, когда вы видите строки в таблице, заполненной повторяющимися данными, настало время отступить и подумать об отношениях.
В конце концов, это то, что дает вам работа с реляционной и структурированной базой данных.
Оптимизировать
Вы можете или не могли заметить странный :index
Я добавил их в генератор моделей, который создает миграцию. Оказывается, это индексы. В SQL индексы оптимизируют вашу базу данных, когда вы запрашиваете информацию по взаимосвязям. Каждый первичный ключ имеет индекс по умолчанию, а реляционные внешние ключи — нет.
Введите это в dbconsole
.schema
Вы должны увидеть что-то вроде:
CREATE INDEX "index_categories_posts_on_category_id_and_post_id"
ON "categories_posts" ("category_id", "post_id");
CREATE INDEX "index_categories_posts_on_post_id_and_category_id"
ON "categories_posts" ("post_id", "category_id");
CREATE INDEX "index_posts_on_user_id" ON "posts" ("user_id");
Поэтому, когда придет время разрабатывать модель вашего домена, вы должны быть экспертом в создании высокопроизводительного решения, которое сделает вашего клиента очень счастливым.
Вывод
Это упаковка. В моей книге базы данных SQL будут присутствовать некоторое время. Они переживут мое поколение и поколение моих детей. Я надеюсь, что вы сможете увидеть, насколько мощен SQL и как эффективно его использовать в реальных задачах.
Вы можете найти остальную часть кода на GitHub .
Счастливого взлома!