Существует множество причин, по которым использование одной большой «таблицы богов» плохо. Я попытаюсь проиллюстрировать проблемы с помощью примера базы данных. Предположим, вы пытаетесь смоделировать спортивные события. Скажем, вы хотите смоделировать игры и команды, играющие в эти игры. Конструкция с несколькими таблицами может выглядеть следующим образом (это очень упрощенно, поэтому не попадите в места, где можно применить больше нормализации):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
и база данных одной таблицы будет выглядеть так
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
Во-первых, давайте посмотрим на создание индексов на этих таблицах. Если бы мне нужен был указатель на родной город для команды, я мог бы легко добавить его в Teams
таблицу или TeamsAndGames
таблицу. Помните, что всякий раз, когда вы создаете индекс, его нужно где-то хранить на диске и обновлять по мере добавления строк в таблицу. В случае с Teams
таблицей это довольно просто. Я положил в новую команду, база данных обновляет индекс. Но как насчет TeamsAndGames
? Ну, то же самое относится и кTeams
пример. Я добавляю команду, индекс обновляется. Но это также происходит, когда я добавляю игру! Даже если это поле будет нулевым для игры, индекс все равно должен быть обновлен и сохранен на диске для этой игры в любом случае. Для одного индекса это звучит не так уж плохо. Но когда вам нужно много индексов для множества сущностей, втиснутых в эту таблицу, вы тратите много места на хранение индексов и много процессорного времени, обновляя их для вещей, к которым они не применяются.
Во-вторых, согласованность данных. В случае использования двух отдельных таблиц я могу использовать внешние ключи от Games
таблицы к Teams
столу, чтобы определить, какие команды играют в игре. И при условии , я делаю HomeTeamId
и AwayTeamId
столбцы не обнуляемым, база данных будет гарантировать , что каждая игра , которую я поставил в есть 2 команды , и что существуют эти команды в моей базе данных. Но как насчет сценария с одним столом? Ну, поскольку в этой таблице есть несколько сущностей, эти столбцы должны быть обнуляемыми (вы можете сделать их не обнуляемыми и засунуть туда данные мусора, но это просто ужасная идея). Если эти столбцы обнуляются, база данных больше не может гарантировать, что при вставке игры в нее входят две команды.
Но что, если вы решите просто пойти на это в любом случае? Вы устанавливаете внешние ключи так, чтобы эти поля указывали на другую сущность в той же таблице. Но теперь база данных просто удостоверится, что эти объекты существуют в таблице, а не что они имеют правильный тип. Вы можете очень легко установить GameHomeTeamId
идентификатор другой игры, и база данных не будет жаловаться вообще. Если вы попробуете это в сценарии с несколькими таблицами, база данных будет соответствовать.
Вы можете попытаться смягчить эти проблемы, сказав: «Ну, мы просто позаботимся о том, чтобы мы никогда не делали этого в коде». Если вы уверены в своей способности писать код без ошибок в первый раз и в своей способности учитывать каждую странную комбинацию вещей, которые может попробовать пользователь, продолжайте. Лично я не уверен в своей способности делать что-либо из этого, поэтому я позволю базе данных дать мне дополнительную сеть безопасности.
(Это становится еще хуже, если в вашем проекте вы копируете все релевантные данные между строками вместо использования внешних ключей. Любые несоответствия правописания / других данных будет трудно устранить. или если это было умышленно (потому что это два разных человека)?)
В-третьих, почти каждый столбец должен быть обнуляемым или заполняться скопированными или ненужными данными. Игра не нуждается в TeamName
или TeamHomeCity
. Так что либо каждая игра нуждается в каком-то заполнителе, либо она должна быть обнуляемой. И если он обнуляем, база данных с радостью возьмет игру без TeamName
. Также потребуется команда без имени, даже если ваша бизнес-логика говорит, что это никогда не должно произойти.
Существует несколько других причин, по которым вам нужны отдельные таблицы (в том числе сохранение здравомыслия разработчика). Есть даже несколько причин, по которым таблица большего размера могла бы быть лучше (денормализация иногда улучшает производительность). Таких сценариев мало, и они далеки друг от друга (и обычно лучше всего их обрабатывать, когда у вас есть показатели производительности, чтобы показать, что это действительно проблема, а не отсутствующий индекс или что-то еще).
Наконец, разработайте что-нибудь, что будет легко поддерживать. То, что это «работает», не означает, что все в порядке. Попытка поддерживать таблицы богов (например, классы богов) - это кошмар. Вы просто настраиваете себя на боль позже.