Dans une application Web sur laquelle je travaille, toutes les opérations de base de données sont abstraites à l'aide de certains référentiels génériques définis sur Entity Framework ORM.
Cependant, afin d'avoir une conception simple pour les référentiels génériques, toutes les tables impliquées doivent définir un entier unique ( Int32
en C #, int
en SQL). Jusqu'à présent, cela a toujours été le PK de la table et aussi le IDENTITY
.
Les clés étrangères sont fortement utilisées et font référence à ces colonnes entières. Ils sont nécessaires à la fois pour la cohérence et pour générer des propriétés de navigation par l'ORM.
La couche application effectue généralement les opérations suivantes:
- chargement initial des données du tableau (*) -
SELECT * FROM table
- Mise à jour -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Supprimer -
DELETE FROM table WHERE Id = IdVal
- Insérer -
INSERT INTO table (cols) VALUES (...)
Opérations moins fréquentes:
- Insertion en
BULK INSERT ... into table
masse - suivie (*) de tous les chargements de données (pour récupérer les identifiants générés) - Suppression en masse - il s'agit d'une opération de suppression normale, mais "volumineuse" du point de vue de l'ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- Mise à jour en masse - il s'agit d'une opération de mise à jour normale, mais "volumineuse" du point de vue de l'ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* toutes les petites tables sont mises en cache au niveau de l'application et presque toutes SELECTs
n'atteindront pas la base de données. Un modèle typique est la charge initiale et beaucoup de INSERT
s, UPDATE
s et DELETE
s.
Selon l'utilisation actuelle de l'application, il y a très peu de chances d'atteindre 100 millions d'enregistrements dans l'une des tables.
Question: Du point de vue d'un administrateur de base de données, y a-t-il des problèmes importants que je peux rencontrer en ayant cette limitation de conception de table?
[ÉDITER]
Après avoir lu les réponses (merci pour les bons commentaires) et les articles référencés, j'ai l'impression que je dois ajouter plus de détails:
Spécificités de l'application actuelle - Je n'ai pas mentionné l'application Web actuelle, car je veux savoir si le modèle peut également être réutilisé pour d'autres applications. Cependant, mon cas particulier est une application qui extrait de nombreuses métadonnées d'un DWH. Les données sources sont assez désordonnées (dénormalisées de manière étrange, présentant des incohérences, aucun identifiant naturel dans de nombreux cas, etc.) et mon application génère des entités clairement séparées. De plus, de nombreux identifiants générés (
IDENTITY
) sont affichés, afin que l'utilisateur puisse les utiliser comme clés professionnelles. Ceci, outre une refactorisation massive du code, exclut l'utilisation des GUID ."ils ne devraient pas être le seul moyen d'identifier de manière unique une rangée" (Aaron Bertrand ♦) - c'est un très bon conseil. Tous mes tableaux définissent également une CONTRAINTE UNIQUE pour garantir que les doublons d'entreprise ne sont pas autorisés.
Conception orientée application frontale par rapport à la conception basée sur une base de données - le choix de conception est dû à ces facteurs
Limitations d'Entity Framework - plusieurs colonnes PK sont autorisées, mais leurs valeurs ne peuvent pas être mises à jour
Limitations personnalisées - le fait d'avoir une seule clé entière simplifie considérablement les structures de données et le code non SQL. Par exemple: toutes les listes de valeurs ont une clé entière et des valeurs affichées. Plus important encore, il garantit que toute table marquée pour la mise en cache pourra être placée dans une
Unique int key -> value
carte.
Requêtes de sélection complexes - cela ne se produira presque jamais car toutes les données des tables de petite taille (<20 à 30 000 enregistrements) sont mises en cache au niveau de l'application. Cela rend la vie un peu plus difficile lors de l'écriture de code d'application (plus difficile à écrire LINQ), mais la base de données est beaucoup plus agréable:
Vues de liste - ne générera aucune
SELECT
requête lors du chargement (tout est mis en cache) ou des requêtes qui ressemblent à ceci:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Toutes les autres valeurs requises sont récupérées via les recherches de cache (O (1)), donc aucune requête complexe ne sera générée.
Modifier les vues - générera des
SELECT
instructions comme celle-ci:SELECT allcolumns FROM BigTable WHERE PKId = value1
(tous les filtres et valeurs sont int
s)