2016-12-07 3 views
-1

Рассмотрите приложение для бильярда. Один тип модели, который вы, возможно, захотите, - это Match, который ссылается на несколько объектов Game, каждый из которых содержит Game объект, содержащий данные для этой игры. Конечно, и Match, и Game ссылки Player, так как вам нужно знать, кто играет. Поэтому, учитывая эту относительно простую модели:Как обрабатывать объекты хранения, ссылающиеся на другие объекты хранения?

class Match 
{ 
    Player Player1; 
    Player Player2; 
    List<Game> Games; 
} 

class Game 
{ 
    Player Player1; 
    Player Player2; 

    // ... scoring data 
} 

class Player 
{ 
    string PlayerName; 
} 

Мы хотим сохранить наш матч до некоторого хранения (тип не имеет значения, но, например, позволяет сказать, что мы храним сгустки JSON сериализованных объектов в лазури).

Самый простой способ, которым мы могли бы сделать это:

storage.SaveBlob(JsonConvert.SerializeObject(myMatch)); 

Но это сохранит несколько копий Player1 и Player2 - один на матч, и один для каждой игры играл в матче.

Мы могли бы изменить Game к:

class Game 
{ 
    [JsonIgnore] 
    Player Player1; 

    [JsonIgnore] 
    Player Player2; 

    // ... scoring data 
} 

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

Мы могли бы снова обновить Game:

class Game 
{ 
    [JsonIgnore] 
    Match Match; 

    [JsonIgnore] 
    Player Player1 => Match.Player1; 

    [JsonIgnore] 
    Player Player2 => Match.Player2; 

    // ... scoring data 
} 

Это упрощает задачу, но все еще требует Match десериализации, чтобы исправить свои свойства. Кроме того, добавление этого типа абстракции создает проблему, заключающуюся в том, что Game объектов должен по части Match. Концептуально это не так (нет причин, по которым вы не могли бы иметь Game, а не часть полного Match), поэтому это кажется плохим подходом.

Другой вариант может изменить Match на:

class Match 
{ 
    Player Player1 => Games.First().Player1; 
    Player Player2 => Games.First().Player2; 
    List<Game> Games; 
} 

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

Целью является чистая сериализация/десериализация при сохранении некоторой нормализации данных. Так что должно быть сделано? Разве это не распространенная проблема?

+0

Это очень широкий вопрос со многими возможными ответами (со многими доступными хранилищами данных - реляционными, столбцами, ключами/значениями, графиком, документом) и многими брендами баз данных в этих категориях. –

+0

Вы не ошибаетесь, но вопрос с несколькими правильными ответами не плох. Я рад услышать любой, который соответствует сценарию :) – Rollie

ответ

-2

Это хорошая работа для реляционной базы данных.

Хранить объекты (матчи, игры, игроки) в отдельных таблицах.

Извлеките их, используя операции «присоединиться».

Что вы предлагаете - это заново изобрести это колесо, которое существует уже много десятилетий.

С другой стороны, похоже, что вы храните исторические данные, которые не будут меняться, поэтому для вас может быть нереплицирующая база данных (NoSQL). Хранение чрезвычайно дешево, поэтому не беспокойтесь о небольшом дублировании данных здесь и там (так как он не будет меняться).

Примечание: если ваше приложение может позволить хранить данные для изменения, а затем дублируются данные зло и его следует избегать любой ценой (так что никто никогда не обновляет одну копию, но не другие), использовать реляционную модель в этом случае ,

+0

Реляционная модель в порядке; для этой проблемы хранение данных несколько не имеет значения, но позволяет сказать, что я использую SQL. Тогда возникает вопрос: с учетом объекта 'Match', как вы можете легко сохранить всю вещь в базе данных без дублирования данных? Реальный вопрос: учитывая объект O, который должен быть представлен в базе данных, но сам ссылается на другие объекты, которые также хранятся в базе данных, как вы можете сохранять и загружать O последовательно, не создавая много специфичной для типа инфраструктуры, какая загрузка/хранения. – Rollie

+0

Дублированные данные * не * злые - это называется * денормализованные * данные. И служит цели. И не следует * избегать любой ценой. Это очень «нормализованная реляционная» точка зрения (и упрямая). –

+0

Также: я не понимаю вашего утверждения о том, что эти данные принадлежат реляционному хранилищу, но если он является историческим/не меняющимся, то он должен войти в базу данных NoSQL. Зачем? И какой тип NoSQL: Document? Ключ/значение? Колонка? Graph? И почему реляционная в первую очередь vs, скажем, график или документ? –

Смежные вопросы