У межах однієї веб-програми, над якою я працюю, всі операції з базою даних абстрагуються за допомогою деяких загальних сховищ, визначених через Entity Framework ORM.
Однак для того, щоб мати просту конструкцію для загальних сховищ, усі залучені таблиці повинні визначати унікальне ціле число ( Int32
у C #, int
у SQL). Досі це завжди було ПК таблиці, а також IDENTITY
.
Іноземні ключі широко використовуються, і вони посилаються на ці цілі стовпці. Вони потрібні як для послідовності, так і для генерації навігаційних властивостей ОРМ.
Прикладний рівень зазвичай виконує такі операції:
- початкове завантаження даних з таблиці (*) -
SELECT * FROM table
- Оновлення -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Видалити -
DELETE FROM table WHERE Id = IdVal
- Вставити -
INSERT INTO table (cols) VALUES (...)
Рідше операції:
- Об'ємна вставка -
BULK INSERT ... into table
супроводжується (*) всім завантаженням даних (для отримання створених ідентифікаторів) - Масове видалення - це звичайна операція видалення, але "об'ємна" з точки зору ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- Масове оновлення - це звичайна операція оновлення, але "об'ємна" з точки зору ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* всі невеликі таблиці кешуються на рівні програми і майже всі SELECTs
не доходять до бази даних. Типовою схемою є початкове навантаження та велика кількість INSERT
s, UPDATE
s та DELETE
s.
Виходячи з поточного використання додатків, є дуже малий шанс коли-небудь досягти 100M записів у будь-якій із таблиць.
Запитання: З точки зору DBA, чи є серйозні проблеми, з якими я можу зіткнутися через обмеження в дизайні таблиці?
[EDIT]
Прочитавши відповіді (дякую за чудові відгуки) та посилання на статті, я відчуваю, що мені потрібно додати більше деталей:
Поточна специфікація додатків - я не згадував про поточну веб-програму, тому що хочу зрозуміти, чи можна використовувати модель для інших додатків. Однак мій конкретний випадок - це програма, яка витягує багато метаданих із DWH. Вихідні дані досить безладні (денормалізовані дивним чином, які мають деякі невідповідності, відсутність природного ідентифікатора у багатьох випадках тощо), і мій додаток генерує чітке відокремлене ціле. Також багато згенерованих ідентифікаторів (
IDENTITY
) відображаються, щоб користувач міг використовувати їх як бізнес-ключі. Це, крім масштабного рефакторингу коду, виключає використання GUID ."вони не повинні бути єдиним способом однозначно визначити ряд" (Аарон Бертран ♦) - це дуже хороша порада. Усі мої таблиці також визначають УНІКАЛЬНЕ ОБМЕЖЕННЯ, щоб переконатися, що копії бізнесу не дозволені.
Дизайн, керований додатком та дизайном, керований базами даних - вибір дизайну обумовлений цими чинниками
Обмеження Entity Framework - кілька ПК у стовпцях дозволено, але їх значення не можна оновити
Спеціальні обмеження - наявність єдиного цілого ключа значно спрощує структури даних та не-SQL-код. Напр .: усі списки значень мають цілий ключ та відображені значення. Що ще важливіше, це гарантує, що будь-яку таблицю, позначену для кешування, можна буде помістити у
Unique int key -> value
карту.
Складні запити вибору - цього майже ніколи не відбудеться, оскільки всі невеликі (<20-30K записів) таблиці таблиць кешуються на рівні програми. Це робить життя трохи складніше при написанні коду програми (складніше писати LINQ), але база даних потрапляє набагато приємніше:
Перегляди списку - не
SELECT
завантажуватиме запитів під час завантаження (усе є кешованим) або запитів, які виглядають так:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Усі інші необхідні значення отримуються через пошук кешу (O (1)), тому складні запити не будуть генеровані.
Редагувати представлення даних - генерувати
SELECT
такі заяви:SELECT allcolumns FROM BigTable WHERE PKId = value1
(усі фільтри та значення int
s)