2013-02-19 3 views
1

Je suis nouveau dans la conception de bases de données et j'ai beaucoup de mal à concevoir une base de données PostgreSQL pour un jeu de combat.Choix des index et des clés primaires pour les performances

Sur ce jeu, les joueurs se battront entre eux, gagnant des ressources pour acheter de meilleures armes et armures. Les combats seront enregistrés pour une révision future et le nombre de combats devrait augmenter rapidement, par exemple, 1k joueurs combattant 1k tours produira 500k records.

L'interactivité du jeu est réduite à dépenser des points pour améliorer l'équipement et les capacités de combat. Les combats sont résolus par la machine.

Détails:

  • Un type spécifique d'arme ou armure ne peuvent être Possesed fois par chaque combattant. Les combattants seront presque exclusivement recherchés par id.
  • Je devrai souvent rechercher quels équipements (armes et/ou armures) sont possédés par un combattant spécifique, mais je ne m'attends pas à rechercher quels combattants possèdent un type spécifique d'arme. Les combats seront souvent recherchés par winner ou loser.
  • Deux données fighters peuvent se battre à plusieurs reprises à des dates différentes, de sorte que le tuple winner - loser n'est pas unique sur la table combats
  • Table fighters contient beaucoup de colonnes qui seront récupérées souvent en même temps (je crée deux objets de la classe "Fighter" avec toutes les informations relatives à chaque fois qu'un combat commence)

Ceci est ma conception actuelle:

CREATE TABLE IF NOT EXISTS weapons (
    id serial PRIMARY KEY, 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS armors (
    id serial PRIMARY KEY, 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS fighters (
    id serial PRIMARY KEY, 
    preferred_weapon INT references weapons(id), 
    preferred_armor INT references armors(id), 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS combats (
    id serial PRIMARY KEY, 
    winner INT references fighters(id), 
    loser INT references fighters(id), 
    *** Game stuff *** 
); 

CREATE TABLE IF NOT EXISTS fighters_weapons (
    fighter INT NOT NULL references fighters(id), 
    weapon INT NOT NULL references weapons(id), 
    PRIMARY KEY(fighter, weapon) 
); 

CREATE TABLE IF NOT EXISTS fighters_armors (
    fighter INT NOT NULL references fighters(id), 
    armor INT NOT NULL references armors(id), 
    PRIMARY KEY(fighter, armor) 
); 

Mes questions sont:

  1. Pensez-vous que mon design est bien adapté?
  2. J'ai vu beaucoup de bases de données exemple contenant une colonne id comme clé primaire sur chaque table. Y a-t-il une raison à cela? Est-ce que je devrais faire cela au lieu des clés primaires de plusieurs colonnes que j'utilise sur fighters_weapons et fighters_armors?
  3. PostgreSQL crée automatiquement des index pour chaque clé primaire, mais il y a plusieurs tables que je ne pense pas rechercher (par exemple combats). Devrais-je supprimer l'index pour la performance? PostgreSQL se plaint d'une contrainte existante.
  4. Comme je recherche fighters_weapons et fighters_armors par fighter, ainsi que combats par winner et loser, pensez-vous que je devrais créer des index pour toutes ces colonnes sur ces tables?
  5. Des conseils pour améliorer la performance? Les opérations les plus utilisées seront: l'insertion et la recherche de combattants, l'interrogation de l'équipement pour un combattant donné et l'insertion de combats.

Merci beaucoup :)

+0

Nitpick mineur: "perdre" est le contraire de "serrer", "perdre" est le contraire de "trouver" (donc votre colonne devrait être appelée "perdant" –

+0

@a_horse_with_no_name C'est vrai .. Merci! –

+0

Techniquement, les «combats» n'ont pas besoin de leur propre clé primaire, ils peuvent utiliser le tuple 'winner' /' loser' comme l'utilisent plusieurs des autres tables d'association.Quel type de jeu est-ce - en temps réel, au tour par tour, etc. Si vous voulez que nous vous donnions plus d'aide, vous aurez besoin de nous donner la disposition complète des différentes tables (en particulier les «combattants»). Hmm .. La plupart des recommandations que j'ai vues ont tendance à dire pour nommer les tables dans le singulier (par exemple «combattant») Vous allez vouloir des indices sur chaque clé primaire, quelle qu'elle soit –

Répondre

0

Pour répondre à vos questions explicites:

2) Il peut être préférable d'utiliser une valeur « naturelle » comme une clé primaire, soit pas un identifiant série, si un existe. Dans les cas où il est peu probable que vous utilisiez un identifiant de série comme identifiant, je dirais qu'il vaut mieux ne pas l'ajouter.

3) A moins d'avoir l'intention d'insérer très rapidement de nombreuses lignes dans la table des combats, cela ne vous fera probablement pas trop mal d'avoir l'index sur la colonne id. 4) Créer un index sur {fighter} n'est pas nécessaire si l'index {fighter, weapon} existe et créer un index sur {fighter} n'est pas nécessaire si l'index {fighter, armor} existe. En général, vous ne bénéficiez pas de la création d'un index qui est le préfixe d'un autre index à plusieurs colonnes. Séparément, créer des index {winner} et {loser} sur les combats semble être une bonne idée étant donné le modèle d'accès que vous avez décrit.

5) Au-delà de la conception de table, il y a quelques paramètres de réglage de base de données que vous pourriez vouloir définir si vous avez installé la base de données vous-même. Si un administrateur de base de données expérimenté a configuré la base de données, il l'a probablement déjà fait pour vous.

+0

Merci beaucoup; c'était très utile. En ce qui concerne 5), je gère moi-même la base de données, mais je n'ai aucune expérience en la matière. Essayera de rechercher des informations concernant le réglage PSQL. –

Questions connexes