W ramach jednej aplikacji WWW, nad którą pracuję, wszystkie operacje na bazach danych są abstrakcyjne przy użyciu niektórych ogólnych repozytoriów zdefiniowanych w Entity Framework ORM.
Jednak, aby mieć prosty projekt dla ogólnych repozytoriów, wszystkie zaangażowane tabele muszą definiować unikalną liczbę całkowitą ( Int32
w C #, int
w SQL). Do tej pory zawsze było to PK na stole, a także IDENTITY
.
Klucze obce są intensywnie używane i odnoszą się do tych liczb całkowitych. Są one wymagane zarówno dla spójności, jak i dla generowania właściwości nawigacyjnych przez ORM.
Warstwa aplikacji zazwyczaj wykonuje następujące operacje:
- wstępne ładowanie danych z tabeli (*) -
SELECT * FROM table
- Aktualizacja -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Usuń -
DELETE FROM table WHERE Id = IdVal
- Wstaw -
INSERT INTO table (cols) VALUES (...)
Rzadsze operacje:
- Wstawianie zbiorcze -
BULK INSERT ... into table
po którym następuje (*) wszystkie ładowanie danych (aby pobrać wygenerowane identyfikatory) - Usuwanie zbiorcze - jest to normalna operacja usuwania, ale „nieporęczna” z perspektywy ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- Aktualizacja zbiorcza - jest to normalna operacja aktualizacji, ale „nieporęczna” z punktu widzenia ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* wszystkie małe tabele są buforowane na poziomie aplikacji i prawie wszystkie SELECTs
nie osiągną bazy danych. Typowy wzór to obciążenie początkowe i wiele INSERT
s, UPDATE
s i DELETE
s.
W oparciu o bieżące użycie aplikacji istnieje bardzo mała szansa na osiągnięcie 100 milionów rekordów w dowolnej tabeli.
Pytanie: Z punktu widzenia DBA, czy istnieją znaczące problemy, na które mogę natknąć się z powodu tego ograniczenia projektowania tabeli?
[EDYTOWAĆ]
Po przeczytaniu odpowiedzi (dziękuję za świetne opinie) i odnośników do artykułów, czuję, że muszę dodać więcej szczegółów:
Bieżąca specyfika aplikacji - nie wspomniałem o bieżącej aplikacji internetowej, ponieważ chcę zrozumieć, czy model może być ponownie użyty również w innych aplikacjach. Jednak moim szczególnym przypadkiem jest aplikacja, która wyodrębnia wiele metadanych z DWH. Dane źródłowe są dość niechlujne (zdenormalizowane w dziwny sposób, mają pewne niespójności, w wielu przypadkach nie mają naturalnego identyfikatora itp.), A moja aplikacja generuje wyraźnie oddzielone byty. Wyświetlanych jest także wiele wygenerowanych identyfikatorów (
IDENTITY
), dzięki czemu użytkownik może użyć ich jako kluczy biznesowych. Oprócz masowego refaktoryzacji kodu wyklucza to użycie identyfikatorów GUID .„nie powinny być jedynym sposobem jednoznacznego zidentyfikowania rzędu” (Aaron Bertrand ♦) - to bardzo dobra rada. Wszystkie moje tabele definiują także WYJĄTKOWE OGRANICZENIE, aby upewnić się, że duplikaty biznesowe nie są dozwolone.
Projektowanie oparte na aplikacji frontonu vs. projektowanie oparte na bazie danych - wybór projektu wynika z tych czynników
Ograniczenia struktury jednostki - dozwolone są wiele kolumn PK, ale ich wartości nie można aktualizować
Ograniczenia niestandardowe - posiadanie jednego klucza liczby całkowitej znacznie upraszcza struktury danych i kod inny niż SQL. Np .: wszystkie listy wartości mają klucz liczby całkowitej i wyświetlane wartości. Co ważniejsze, gwarantuje, że każda tabela oznaczona do buforowania będzie mogła umieścić na
Unique int key -> value
mapie.
Złożone zapytania dotyczące wyboru - prawie nigdy tak się nie stanie, ponieważ wszystkie małe tabele (<20-30 000 rekordów) są buforowane na poziomie aplikacji. To sprawia, że życie jest trochę trudniejsze podczas pisania kodu aplikacji (trudniej napisać LINQ), ale baza danych jest znacznie ładniejsza:
Widoki list - nie będą generować żadnych
SELECT
zapytań przy ładowaniu (wszystko jest buforowane) lub zapytań, które wyglądają tak:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Wszystkie pozostałe wymagane wartości są pobierane przez wyszukiwanie pamięci podręcznej (O (1)), więc nie będą generowane żadne złożone zapytania.
Edytuj widoki - wygeneruje
SELECT
takie instrukcje:SELECT allcolumns FROM BigTable WHERE PKId = value1
(wszystkie filtry i wartości są int
s)