одна таблиця без додаткових стовпців проти кількох таблиць, які повторюють схему


13

Я працюю над проектом, де в якийсь момент мені потрібно було прийняти рішення про те, чи потрібно в базі даних мати єдину таблицю з декількома стовпцями, яку використовує не кожен запис, або кілька таблиць із дубльованою схемою.

Я створюю спортивну інформаційну програму, яка може працювати з кількома видами спорту. Наприклад, ми можемо впоратися з NBA, NHL, MLB, NFL. Кожен вид спорту має дуже схожі поняття - Команди, Розклад, Травми, Інформація про гравця.

Звичайно, наше джерело даних не дає нам кожної частини даних в одній схемі. Кожен вид спорту має різні схеми, до яких ми отримуємо дані від нашого постачальника.

Оскільки не було достатньо часу (вимог клієнта) для попереднього аналізу каналів даних, щоб визначити спільність, я підняв ставку і взяв «безпечну ставку» та склав окремі окремі таблиці для кожного виду спорту, а не один набір таблиць, який усі використовувані види спорту.

Результатом є дублювання схеми в декількох таблицях, а також копіювання інтерфейсів до бази даних (наприклад, збережених програм). У мене є щось на зразок NBA_Game, NFL_Game, NBA_Team, NFL_Team тощо. Кожна таблиця може мати кілька властивостей, яких не має інша, і кілька спільних. це продовжується, скажімо, 5-10 столів у 4 або 5 видах спорту. Я все ще не впевнений, що це зовсім погано - альтернатива, що має єдиний набір столів, на якому були властивості, які не всі види спорту могли б використовувати, може, і сама по собі була непростою.

Хтось, хто зробив це, зіткнувся з підводними камінням такого типу дизайну і міг би поділитися тут своїм досвідом? Що може допомогти мені дізнатися зараз, а не навчитися важкому шляху? Ви зробили це по-іншому, маючи одну велику таблицю / набір таблиць із стовпцями, які використовували б не кожен запис? Які підводні камені ви зіткнулися з цим?

Чи є якась альтернатива, така як успадкування столів, яку ви використовували в минулому, яка працювала краще?

Спасибі

Відповіді:


12

Зрештою, це зводиться до використання та архітектури.

Архітектура

Чи обробляє система "будь-який вид спорту"? Чи є ідея, яку ви наділи на капелюх космонавта з архітектури, і побудуєте загальну систему, яка може працювати з будь-яким майбутнім видом спорту, який може навіть не існувати сьогодні?

Якщо так, очевидно, що динамічно названі таблиці є величезним болем, тому було б доцільно створити схему, яка підтримує російські види спорту, якщо потрібно.

Однак, у мене дуже сильна упередженість щодо такого підходу: це майже завжди більше роботи і призводить до гірших результатів. Створення окремого інтерфейсу, схеми тощо для кожного виду спорту в кінцевому підсумку призведе до кращого користувальницького досвіду та легшого обслуговування коду, навіть якщо це означає деяку поверхневу кількість дублювання (як уникнути / мінімізувати це окреме питання).

Як ви поводитесь із гравцями, які займаються кількома видами спорту? Чи отримують вони два записи (наприклад, ви ставитесь до різних людей) чи намагаєтесь зробити щось конкретне з ними?

Використовуйте

Тож припустимо, що ви не займаєтесь спортом динамічно (наприклад, якщо хтось хоче додати новий вид спорту, для його додавання потрібні зусилля з розвитку).

Чи є коли-небудь час, коли ви показуєте гравців (або будь-який інший предмет, який ви згадали) з кількох видів спорту одночасно?

Я бачив це як функцію пошуку, де ви могли шукати за іменем гравця чи команди (незалежно від спорту), але крім цього я не уявляю багатьох випадків використання.

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

Альтернативні схеми

Перегляди

Я фанат KISS. За 15+ років розробки програмного забезпечення я продовжую відступати від філософії "будуй найпростішу річ, яка працює".

Тож моя початкова реакція, припускаючи, що функція пошуку крос-спорту є єдиним випадком використання, полягає у створенні переглядів:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

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

Я б спробував зберегти всі речі, що стосуються спорту, у визначенні View, тому в коді пошуку не повинно бути багато чи якийсь конкретний код (крім того, можливо, ви знаєте, як зв’язатися з /nhl/players/player-namevs /nfl/...або, однак, це робить ваша програма).

Спадковість таблиці

Успадкування таблиці може працювати, але досить складно. Я не маю багато досвіду з цим, і насправді, я думаю, що кожного разу, коли я брав участь в його оцінці, в кінцевому підсумку робив щось простіше (як я пропоную тут).

Отож особисто мені ще не зрозуміти, чому це було б корисно, але, можливо, є переконливий випадок використання (про який я не знаю), який виправдовує складність (наприклад, наслідування таблиці вирішує випадок використання краще, ніж будь-яке інше рішення) .

Окремі таблиці для специфічних для спорту ознак

Ви можете створити єдину playersтаблицю, яка містить атрибути, спільні для всіх гравців усіх видів спорту, а потім інший набір таблиць на зразок, nhl_players_detailsщо містить ідентифікатор гравця та стовпці з додатковою інформацією про програвач. Якщо є багато загальних атрибутів, або ви багато використовуєте "всіх гравців з усіх видів спорту", то це може мати сенс.

Пари ключових значень для спортивних атрибутів

Повністю альтернативний підхід: є playersтаблиця (знову ж , з загальними атрибутами , як ім'я) , а потім в player_dataтаблиці , яка має PlayerId, Sport, Attribute, Value. Введені імена атрибутів були б специфічними для спорту. Це дозволяє по суті додавати нові атрибути без зміни схеми (ваш код все одно повинен знати, щоб завантажувати / відображати їх). Недолік полягає в тому, що ви втрачаєте деяку цілісність: значення, як правило, є рядковим полем, тому ваш код програми повинен бути стійким і обробляти потенційні збої, перетворюючи рядок valueу конкретний тип даних (наприклад, ціле число).

Ця концепція, звичайно, може бути застосована до команд, ігор тощо.


Пошук рішення застарілого проекту дозволить отримати декілька справжніх типів і таблиць, згадка про погляди, про які я забув, справді допомогла запропонувати ще одне можливе рішення для мого дослідження. Дякую.
FullStackFool

5

Ви говорите про нормалізацію бази даних . Можливо, ви з полегшенням дізнаєтесь, що немає такої речі, як ідеальна модель даних, і що більше нормалізації не завжди краще. Нормалізація може вимагати витрат з точки зору ясності моделі даних та продуктивності бази даних. Тому найкраща модель для вибору буде залежати від ваших потреб використання.

Зрештою, ваші приклади здаються досить схожими в концепції (X_Game vs Y_Game та X_Team vs Y_Team), що додаткові накладні витрати на кілька стовпців не здаються необґрунтованими. Це означає, що якщо кожен вид спорту додасть кілька десятків додаткових стовпців до столу, це було б справді непростим.

У цьому випадку ви можете розглянути гібридну модель, коли загальні дані зберігаються в центральній таблиці, але специфічні для спорту дані зберігаються у пов'язаній структурі даних. Щось на зразок:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}

Це те, що я збирався запропонувати, плюс, можливо, стовпець в таблиці ігор із зазначенням типу гри. Я розумію, що про це можна зробити висновок, приєднавшись до інших таблиць, але якщо кількість видів ігор зростає, це починає набридати.
Рорі Хантер

Абсолютно - це просто скелетна модель для ілюстрації основних взаємозв'язків та деяких прикладів того, що може бути загальними даними щодо даних, пов'язаних зі спортом.
Midnotion
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.