Реляционное и нереляционное моделирование данных - какая разница
Я новичок в базах данных, и я никогда не работал с какой-либо СУБД. Однако я получаю основную идею реляционных баз данных. По крайней мере, я думаю, что я делаю: -)
Скажем, у меня есть пользовательская база данных со следующими свойствами для каждого пользователя:
В реляционной базе данных я бы, например, смоделировал ее в таблице с именем user
и иметь вторую таблицу под названием location
И location_id
- это внешний ключ (ссылка) к записи в таблице location
. Если я правильно понимаю, преимущество здесь, если почтовый индекс для определенного города меняется, мне нужно изменить только одну запись.
Итак, перейдите в нереляционную базу данных, где я начал играть с Google App Engine. Здесь я бы действительно моделировал его, как он был записан первым в спецификации. У меня есть вид user
:
class User(db.Model):
name = db.StringProperty()
zip = db.StringProperty()
city = db.StringProperty()
Преимущество состоит в том, что мне не нужно присоединяться к двум "таблицам", но недостатком является то, что при изменении zip-кода я должен запустить script, который проходит через все пользовательские записи и обновляет почтовый индекс, правильно?
Итак, теперь есть еще один вариант в 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 и city, я должен запустить второй запрос. Но в другом случае, чтобы внести изменения в почтовый индекс, я должен запускать всех существующих пользователей.
Итак, каковы последствия этих двух возможностей моделирования в нереляционной базе данных, например в хранилище данных Google. И каковы типичные варианты использования для обоих из них, то есть когда я должен использовать один и другой.
Также как дополнительный вопрос, если в базе данных без отношения я могу моделировать точно то же самое, что я могу моделировать в реляционной базе данных, почему я должен использовать реляционную базу данных вообще?
Извините, если некоторые из этих вопросов звучат наивно, но я уверен, что они помогут пару людей, которые новичок в системах баз данных, чтобы лучше понять.
Ответы
Ответ 1
В моем опыте самое большое различие заключается в том, что нереляционные хранилища данных заставляют вас моделировать, основываясь на том, как вы будете запрашивать, из-за отсутствия объединений и того, как вы будете писать, из-за ограничений транзакций. Это, конечно, приводит к очень денормализованным моделям. Через некоторое время я начал определять все запросы сначала, чтобы не передумывать модели позже.
Из-за гибкости реляционных db вы можете думать о каждом семействе данных в отдельности, создавать отношения между ними и в конечном запросе, как вы хотите (злоупотребление соединениями во многих случаях).
Ответ 2
Представьте, что GAE имеет два режима для режима хранилища данных: RDMS-режим и не-RDMS-режим.
Если я возьму ваш пример ReferenceProperty с целью "перечислить всех пользователей и все их почтовые индексы" и написать код для печати всех этих файлов.
Для хранилища данных [fictional] RDMS это может выглядеть так:
for user in User.all().join("location"):
print("name: %s zip: %s" % (user.name, user.location.zip))
Наша система RDMS обработала де-нормализацию данных за сенсами и сделала хорошую работу по возврату всех данных, которые нам нужны в одном запросе. Этот запрос имел немного накладных расходов, поскольку он должен был сшить наши две таблицы.
Для не-RDMS Datastore наш код может выглядеть так:
for user in User.all():
location = Location.get( user.location )†
print("name: %s zip: %s" % (user.name, location.zip))
Здесь Datastore не может помочь нам присоединиться к нашим данным, и мы должны сделать дополнительный запрос для каждого объекта user
для получения location
, прежде чем мы сможем его распечатать.
Это, по сути, означает, почему вы хотите избежать чрезмерно нормализованных данных в системах, отличных от RDMS.
Теперь все логически нормализуют свои данные до некоторой степени, если используют RDMS или нет, трюк заключается в том, чтобы найти компромисс между удобством и производительностью для вашего варианта использования.
† это недопустимый код appengine, я просто иллюстрирую, что user.location
вызывает запрос db. Кроме того, никто не должен писать код, как мой экстремальный пример выше, вы можете работать с продолжением выборки связанных объектов, предположив, что вы выбираете места в пакетах вверх.
если в базе данных, не относящейся к отношениям, я могу моделировать точно то же, что я могу моделировать в реляционной базе данных, почему я должен использовать реляционную базу данных вообще?
relational-DB превосходит при хранении тысяч и миллионов строк сложных взаимосвязанных моделей данных и позволяет выполнять невероятно сложные запросы для реорганизации и доступа к этим данным.
не-RDB превосходит при хранении миллиардов + строк простых данных и позволяет вам получать эти данные с более простыми запросами.
Выбор должен лежать на вашем прецеденте. Более простая структура нереляционной модели и конструктивных ограничений, которые прилагаются к ней, является одним из основных способов, которыми AppEngine может обещать масштабировать приложение со спросом.
Ответ 3
Ваше понимание концепции реляционной базы данных ошибочно. Реляционные базы данных организуют свои данные в отношениях, которые содержат набор кортежей того же типа. Чтобы перефразировать, данные хранятся в таблицах с каждой строкой, содержащей одинаковое количество полей с одинаковыми типами в том же порядке.
Приведенный вами пример, в котором используется внешний ключ, демонстрирует нормализацию базы данных. Это концепция, которая может применяться как к реляционным, так и к другим типам баз данных.
Извините, я не могу ответить на ваши вопросы о системе хранения Google, но, надеюсь, это прояснит ваше понимание, чтобы узнать.