Подтвердить что ты не робот

Реляционное и нереляционное моделирование данных - какая разница

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

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

  • пользователь
    • 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()

Преимущество состоит в том, что мне не нужно присоединяться к двум "таблицам", но недостатком является то, что при изменении 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. И каковы типичные варианты использования для обоих из них, то есть когда я должен использовать один и другой.

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

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

4b9b3361

Ответ 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, но, надеюсь, это прояснит ваше понимание, чтобы узнать.