Реляционное и нереляционное моделирование данных - в чем разница - PullRequest
20 голосов
/ 13 мая 2011

Я новичок в базах данных и никогда не работал ни с одной СУБД. Однако я получаю основную идею о реляционных базах данных. По крайней мере, я так думаю; -)

Допустим, у меня есть пользовательская база данных со следующими свойствами для каждого пользователя:

  • пользователь
    • ID
    • имя
    • молния
    • город

В реляционной базе данных Я бы, например, смоделировал ее в таблице с именем user

  • пользователь
    • ID
    • имя
    • LOCATION_ID

и иметь второй стол с именем location

  • место
    • ID
    • молния
    • город

И location_id - это внешний ключ (ссылка) на запись в таблице location. Если я правильно понимаю, преимущество здесь, если почтовый индекс для определенного города меняется, мне нужно изменить только одну запись.

Итак, давайте перейдем к нереляционной базе данных , где я начал играть с Google App Engine. Здесь я действительно смоделировал бы это, как это было сначала записано в спецификациях. У меня есть вид user:

class User(db.Model):
    name = db.StringProperty()
    zip = db.StringProperty()
    city = db.StringProperty()

Преимущество состоит в том, что мне не нужно объединять две «таблицы», но недостатком является то, что, если почтовый индекс изменяется, мне нужно запустить скрипт, который просматривает все записи пользователя и обновляет почтовый индекс, правильно?

Итак, теперь в Google App Engine есть еще одна опция, которая должна использовать ReferenceProperties. Я мог бы иметь два вида: user и location

class Location(db.Model):
    zip = db.StringProperty()
    city = db.StringProperty()

class User(db.Model):
    name = db.StringProperty()
    location = db.ReferenceProperty(Location)

Если я не ошибаюсь, у меня теперь точно такая же модель, как в описанной выше реляционной базе данных. Что меня сейчас интересует, так это, прежде всего, то, что я только что сделал неправильно, и это разрушает все преимущества нереляционной базы данных. Я понимаю, что для получения значения zip и города мне нужно выполнить второй запрос. Но в другом случае, чтобы внести изменения в почтовый индекс, мне нужно пройти через всех существующих пользователей.

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

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

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

Ответы [ 3 ]

17 голосов
/ 13 мая 2011

По моему опыту, самое большое отличие состоит в том, что нереляционные хранилища данных вынуждают вас моделировать на основе того, как вы будете запрашивать, из-за отсутствия объединений и того, как вы будете писать, из-за ограничений транзакций. Это, конечно, приводит к очень денормализованным моделям. Через некоторое время я начал определять все запросы first , чтобы избежать необходимости переосмысливать модели позже.

Из-за гибкости реляционных БД вы можете думать о каждом семействе данных по отдельности, создавать отношения между ними и в конечном запросе как хотите (злоупотребление объединениями во многих случаях).

11 голосов
/ 13 мая 2011

Представьте, что GAE имеет два режима для хранилища данных: режим RDMS и режим не RDMS.Если я возьму ваш пример ReferenceProperty с целью «перечислить всех пользователей и все их почтовые индексы» и напишу некоторый код, чтобы распечатать их все.

Для хранилища данных [вымышленного] RDMS-режима этоможет выглядеть так:

for user in User.all().join("location"):
    print("name: %s zip: %s" % (user.name, user.location.zip))

Наша система RDMS справилась с денормализацией данных за пределами поля и выполнила хорошую работу по возвращению всех данных, которые нам были нужны, в одном запросе.У этого запроса были небольшие накладные расходы, поскольку он должен был объединить наши две таблицы.

Для хранилища данных без RDMS наш код может выглядеть следующим образом:

for user in User.all():
    location = Location.get( user.location )†
    print("name: %s zip: %s" % (user.name, location.zip))

Здесь хранилище данных не может помочь нам присоединиться к нашим данным, и мы должны сделать дополнительный запрос для каждого объекта user, чтобы получить location, прежде чем мы сможем его распечатать.

По сути, именно поэтому вы хотите избежать чрезмерно нормализованных данных в системах без RDMS.

Теперь все логически нормализуют свои данные до некоторой степени, используют ли они RDMS или нет, трюкчтобы найти компромисс между удобством и производительностью для вашего варианта использования.

† это недопустимый код приложения, я просто показываю, что user.location вызовет запрос в БД.Кроме того, никто не должен писать код, подобный моему крайнему примеру выше, вы можете обойти дальнейшую выборку связанных сущностей, скажем, выборку местоположений в пакетах заранее.

, если в нереляционной базе данныхЯ могу моделировать в точности то же, что и моделирование в реляционной базе данных, зачем мне вообще использовать реляционную базу данных?

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

Превосходство не-RDB в хранении миллиардов + строк простых данных и позволяет извлекать эти данные с помощью более простых запросов.

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

4 голосов
/ 13 мая 2011

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

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

Извините, я не могу ответить на ваши вопросы о системе хранения Google, но, надеюсь, это прояснит ваше понимание настолько, чтобы это выяснить.

...