2009-10-21 3 views
3

Je dois stocker une grande table (plusieurs millions ou lignes) qui contient un grand nombre de champs définis par l'utilisateur (inconnus au moment de la compilation, mais probablement entre 20 et 40 des champs). Il est très important (performance-sage) pour moi d'être en mesure d'interroger les données basées sur ces champs personnalisés, c'est-à-dire "Sélectionnez les lignes où cet attribut a cette valeur, cet attribut est cette valeur, etc." Chaque requête comporte de 20 à 30 clauses WHERE.Implémentation et indexation des champs définis par l'utilisateur dans un DB SQL

Mes idées à ce jour:

  1. Changer le schéma de base de données chaque fois qu'un nouveau champ utilisateur est mis en œuvre. Conservez chaque champ défini par l'utilisateur en tant que colonne dans la table. Ajoutez et maintenez des index sur chaque colonne personnalisée. Comment construire correctement ces index est un gros problème, car je ne sais pas quels attributs (colonnes) seront utilisés dans les requêtes WHERE.

  2. Stockez les champs personnalisés en tant que colonne de type XML. Comme je comprends de SQL2005 je peux interroger à l'intérieur du XML dans les colonnes de type XML. Pas si sûr de la performance cependant.

  3. Entity Attribute Value. C'est ce que j'utilise maintenant, mais c'est une douleur.

Une suggestion?

Modifier: Quelques précisions sur mes besoins. J'ai une table, 40 à 50 millions de lignes de numéros (disons) ID et divers attributs associés à ces ID.

Disons que 20 millions d'entre eux ont « CustomAttribute1 » égal à 2, puis 5 millions ont « CustomAttribute2 » égal à « Oui » et 3 millions ont « CustomAttribute20 » égal à « Non »

I need a FAST method of returning all IDs where: 
    1. CustomAttribute1 = 2 
    2. CustomAttribute2 = 'Yes' 
    3. CustomAttribute4 = null 
    4. CustomAttribute20 != 'No' 
    etc... 

Nous ceci est implémenté comme EAV: la requête select est un cauchemar à implémenter et maintenir, il faut beaucoup de temps pour retourner le résultat, et le plus anormalement le DB évolue vers des tailles énormes même pour de petites quantités de données, ce qui est bizarre puisque l'EAV est essentiellement Normaliser les données mais je suppose que tous les index prennent beaucoup d'espace.

+0

Pouvez-vous clarifier ce que vous faites avec ceci, c'est-à-dire quel type de données est dans le tableau. De plus, ces champs personnalisés sont-ils les seules colonnes? –

Répondre

4

Il semble que vous ayez répertorié vos options disponibles. EAV peut être pénible pour l'interrogation (et lent, selon le nombre de critères que vous voulez rechercher simultanément), mais il a tendance à être le plus "sain" et l'implémentation indépendante du SGBDR.

Modifier le schéma est un non-non ... évidemment, cela peut être fait, mais une telle pratique est odieuse. Je n'approuve pas.

L'option XML est une solution et SQL Server peut interroger à l'intérieur de la structure. Je ne suis pas certain des autres SGBDR, et vous n'indiquez pas celui que vous utilisez dans la publication ou les tags.

Si vous allez interroger plusieurs attributs (disons 20+) simultanément, alors je recommanderais probablement la solution XML juste pour limiter le nombre de jointures que vous aurez à faire. En dehors de cela, je voudrais rester avec EAV.

+0

Quelle est la vitesse à interroger XML par rapport à l'interrogation des colonnes normales. Est-ce qu'ils indexent même le XML? – Radu094

+0

Vous pouvez créer des index sur le fichier XML. Je laisserai un benchmarking spécifique à ceux qui ont plus d'expérience avec la base de données XML que moi, mais il y a une bonne quantité d'informations disponibles sur Internet à propos de l'interrogation XML et de l'indexation dans SQL Server. –

0

Vous pouvez représenter tous les champs définis par l'utilisateur avec une colonne XML, par ex. "Mais je ne suis pas sûr de l'impact que cela aurait sur les performances, mais c'est certainement la plus belle façon de gérer les UDF dans une base de données à mon avis."

<UDF> 
     <Field Name="ConferenceAddress" DBType="NVarChar" Size="255">Some Address</Field> 
     <Field Name="ConferenceCity" DBType="NVarChar" Size="255">Some City</Field> 
     ...etc 
    </UDF> 

Alors ce que je ferais est de mettre un déclencheur sur la table de sorte que lorsque la colonne est mise à jour, il reconstitue une vue de la table qui tire les valeurs xml sous forme de colonnes dans la vue. Verrouillez la vue, etc. Ensuite, je créerais une procédure stockée pour mettre à jour le XML afin qu'il fonctionne pour n'importe quelle colonne XML suivant le formatage XML du champ défini par l'utilisateur, par exemple Insérer/Mettre à jour/Supprimer./Obtenir

GetUDFFieldValue AddUDFField Haut dateUDFField DeleteUDFField

--shared Paramètres NomTable NomColonne (par exemple, utilisez le SQL dynamique pour obtenir la table XML de X par le nom de colonne X pour le rendre universel/générique pour tous vos champs UDF)

Voici un article sur XML Performance Optimization de Sql Server 2005 (ne pas voir un équivalent dans newer versions):

http://technet.microsoft.com/en-us/library/ms345118(v=sql.90).aspx

Enfin:

Êtes-vous sûr que vous avez même un SGBDR? NoSql est un meilleur ajustement pour les champs générés par l'utilisateur, je pourrais même envisager d'utiliser à la fois NoSql et Sql Server.

Questions connexes