Я бы порекомендовал , а не , пытаясь расширить таблицу по горизонтали, это операция, которую вы должны принять сознательно.
Вместо этого я бы порекомендовал хранить значения в виде пар имя / значение. У вас могут быть таблицы с определенными типами (скажем, вам нужно целочисленное значение в паре с ключом), а затем вы можете выбрать их в словаре для пользователя.
У вас также есть таблица с ключами, если вы заинтересованы в репликации значений ключей.
Например, у вас есть UserDefinedKey
таблица
UserDefinedKeyId (int, PK) Key (varchar(?))
-------------------------- ----------------
1 'My Website'
2 'My favorite color'
Тогда у вас будет UserDefinedString
таблица (для строковых значений)
UserDefinedStringId UserId UserDefinedKeyId Value
(int, PK) (int, FK) (int, FK) (varchar(max))
------------------- --------- ---------------- --------------
1 1 1 'http://stackoverflow.com'
2 1 2 'Blue'
3 2 2 'Red'
Возможно, вы захотите разместить уникальный индекс в полях UserId
и UserDefinedKeyId
, чтобы запретить людям вводить несколько значений для одного и того же ключа (если вы хотите, используйте отдельную таблицу без * 1020). * уникальное ограничение).
Затем, когда вы хотите добавить значение для пользователей, вы добавляете его в таблицу UserDefinedKey
, а затем удаляете свою логику из этой таблицы и других таблиц, которые содержат значения.
Еще одно преимущество вертикального хранения значений заключается в том, что вы не тратите пространство на столбцы со значениями, которые не используются всеми пользователями.
Например, предполагая, что вы используете подход, модифицирующий таблицу, для приведенных выше атрибутов вы получите:
UserId WebSite Color
------ ------- -----
1 http://stackoverflow.com Blue
2 (null) Red
Теперь предположим, что третий пользователь приходит и добавляет значение Favorite Sports Team
, и они единственные, кто его использует, тогда таблица выглядит так:
UserId WebSite Color FavoriteSportsTeam
------ ------- ----- ------------------
1 http://stackoverflow.com Blue (null)
2 (null) Red (null)
3 (null) (null) Yankees
По мере роста числа пользователей и атрибутов количество имеющихся у вас разреженных данных резко возрастет.
Теперь, предполагая, что вы используете SQL Server 2008, вы можете использовать разреженных столбцов , если вы этого не сделаете, ваша таблица станет огромной, но не будет много данных.
Кроме того, использование разреженных столбцов не умаляет того факта, что довольно просто использовать язык определения данных (DDL) для изменения схемы на лету.
Кроме того, Entity Framework не сможет адаптировать свою объектную модель для учета новых атрибутов; каждый раз, когда вы добавляете атрибут, вам нужно будет пойти и добавить атрибут в вашу объектную модель, перекомпилировать и повторно развернуть.
При вертикальном подходе требуется больше работы, но она будет бесконечно гибкой, а также более эффективно использует пространство вашей базы данных.