Comment créer des relations dans MySQL

97

En classe, nous «étudions» tous les bases de données et tout le monde utilise Access. Lassé de cela, j'essaie de faire ce que le reste de la classe fait, mais avec des commandes SQL brutes avec MySQL au lieu d'utiliser Access.

J'ai réussi à créer des bases de données et des tables, mais maintenant comment établir une relation entre deux tables?

Si j'ai mes deux tables comme ceci:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

et

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    PRIMARY KEY ( customer_id )
)

Comment créer une «relation» entre les deux tables? Je souhaite que chaque compte se voit attribuer un identifiant client (pour indiquer à qui il appartient).

Josh Hunt
la source
48
"JE REFUSE d'étudier Access, je vais étudier un VRAI moteur de base de données: MySQL" C'est l'esprit! Félicitations = D
Metafaniel
2
Notez que les contraintes de clé étrangère n'implémentent pas les relations, elles implémentent l'intégrité. L'association entre account_id et customer_id dans la table des comptes implémente la relation entre les entités respectives.
reaanb
1
"C'est l'esprit!", Du moment que c'est mysql avec InnoDB, pas MyISAM. Postgreqsl a également quelques fonctionnalités intéressantes sur MySQL qui valent la peine d'être examinées.
jgmjgm

Réponses:

103

Si les tables sont innodb, vous pouvez les créer comme ceci:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id ), 
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
) ENGINE=INNODB;

Vous devez spécifier que les tables sont innodb car le moteur myisam ne prend pas en charge la clé étrangère. Regardez ici pour plus d'informations.

Eric Hogue
la source
J'ai vu dans un article, qu'il n'est pas nécessaire de spécifier la clause ENGINE = InnoDB si InnoDB est défini comme moteur de stockage par défaut, peut vérifier à l'aide de la commande (mysql> SELECT @@ default_storage_engine;)
Arun
80

comme ehogue l'a dit, mettez ceci dans votre CREATE TABLE

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

Sinon, si vous avez déjà créé la table, utilisez une commande ALTER TABLE:

ALTER TABLE `accounts`
  ADD CONSTRAINT `FK_myKey` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`) ON DELETE CASCADE ON UPDATE CASCADE;

Une bonne façon de commencer à apprendre ces commandes est d'utiliser les outils d'interface graphique MySQL , qui vous offrent une interface plus «visuelle» pour travailler avec votre base de données. Le véritable avantage de cela (par rapport à la méthode Access), est qu'après avoir conçu votre table via l'interface graphique, cela vous montre le SQL qu'il va exécuter, et vous pouvez donc en tirer des leçons.

nickf
la source
3
Votre réponse est la meilleure solution
Omar
14
CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

and

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
)

How do I create a 'relationship' between the two tables? I want each account to be 'assigned' one customer_id (to indicate who owns it).

Vous devez vous demander s'il s'agit d'une relation 1 à 1 ou 1 sur plusieurs. Autrement dit, est-ce que chaque compte a un client et chaque client a un compte. Ou y aura-t-il des clients sans compte. Votre question implique ce dernier.

Si vous souhaitez avoir une relation stricte de 1 à 1, fusionnez simplement les deux tables.

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
)

Dans l'autre cas, la manière correcte de créer une relation entre deux tables est de créer une table de relations.

CREATE TABLE customersaccounts(
    customer_id INT NOT NULL,
    account_id INT NOT NULL,
    PRIMARY KEY (customer_id, account_id)
    FOREIGN KEY customer_id references customers (customer_id) on delete cascade,
    FOREIGN KEY account_id  references accounts  (account_id) on delete cascade
}

Ensuite, si vous avez un customer_id et que vous voulez les informations de compte, vous vous inscrivez sur les comptes et comptes clients:

SELECT a.*
    FROM customersaccounts ca
        INNER JOIN accounts a ca.account_id=a.account_id
            AND ca.customer_id=mycustomerid;

En raison de l'indexation, ce sera incroyablement rapide.

Vous pouvez également créer une VUE qui vous donne l'effet du tableau des comptes clients combinés tout en les gardant séparés

CREATE VIEW customeraccounts AS 
    SELECT a.*, c.* FROM customersaccounts ca
        INNER JOIN accounts a ON ca.account_id=a.account_id
        INNER JOIN customers c ON ca.customer_id=c.customer_id;
user3842431
la source
1
Je pense que vous vouliez dire ca.non ac.(3 endroits).
Vue elliptique le
vous avez écrit PRIMARY KEY (customer_id, account_id)sans virgule après
theonlygusti
11

En ajoutant au commentaire de ehogue, vous devez faire correspondre la taille des clés sur les deux tables. Plutôt que

customer_id INT( 4 ) NOT NULL ,

fais-le

customer_id INT( 10 ) NOT NULL ,

et assurez-vous que votre colonne int dans la table customers est également int (10).

Zak
la source
7

Certains moteurs MySQL prennent en charge les clés étrangères. Par exemple, InnoDB peut établir des contraintes basées sur des clés étrangères. Si vous essayez de supprimer une entrée dans une table qui a des dépendants dans une autre, la suppression échouera.

Si vous utilisez un type de table dans MySQL, tel que MyISAM, qui ne prend pas en charge les clés étrangères, vous ne liez les tables nulle part à l'exception de vos diagrammes et requêtes.

Par exemple, dans une requête, vous liez deux tables dans une instruction SELECT avec une jointure:

SELECT a, b from table1 LEFT JOIN table2 USING (common_field);
Gary Richardson
la source
2

Voici quelques ressources qui vous aideront à démarrer: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase et http://code.tutsplus.com/articles/sql-for-beginners-part- 3-relations-bases-de-données - net-8561

Aussi, comme d'autres l'ont dit, utilisez une interface graphique - essayez de télécharger et d'installer Xampp (ou Wamp) qui exécute le logiciel serveur (Apache et mySQL) sur votre ordinateur. Ensuite, lorsque vous accédez à // localhost dans un navigateur, sélectionnez PHPMyAdmin pour commencer à travailler visuellement avec une base de données mySQL. Comme mentionné ci-dessus, utilisé innoDB pour vous permettre d'établir des relations comme vous l'avez demandé. Permet de voir plus facilement ce que vous faites avec les tables de la base de données. N'oubliez pas d'arrêter les services Apache et mySQL lorsque vous avez terminé - ceux-ci peuvent ouvrir des ports qui peuvent vous exposer à des menaces de piratage / malveillant.

user3659515
la source
Si vous configurez apache et mysql pour ne servir que les requêtes locales, vous n'avez pas besoin de les arrêter. En outre, les utilisateurs devraient avoir au moins un pare-feu logiciel installé s'ils installent ce type de services. Cela dit, de nombreux routeurs domestiques sont équipés d'un pare-feu intégré, de sorte que les ports ne doivent pas être ouverts de toute façon à moins qu'ils n'aient été ouverts par quelqu'un ayant accès au routeur.
Chris
1

L'une des règles que vous devez savoir est que la colonne de table à laquelle vous souhaitez faire référence doit être avec le même type de données que la table de référence. 2 si vous décidez d'utiliser mysql, vous devez utiliser InnoDB Engine car selon votre question, c'est le moteur qui prend en charge ce que vous voulez réaliser dans mysql.

Ci-dessous, le code, essayez-le bien que les premières personnes à répondre à cette question aient fourni à 100% d'excellentes réponses et veuillez les considérer toutes.

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY (account_id)
)ENGINE=InnoDB;

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
     PRIMARY KEY ( account_id ), 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
)ENGINE=InnoDB; 
Musa
la source
0
create table departement(
    dep_id      int primary key auto_increment,
    dep_name    varchar(100) not null,
    dep_descriptin      text,
    dep_photo       varchar(100) not null,
    dep_video       varchar(300) not null
);

create table newsfeeds(
    news_id         int primary key auto_increment,
    news_title      varchar(200) not null,
    news_description    text,
    news_photo          varchar(300) ,
    news_date           varchar(30) not null,
    news_video          varchar(300),
    news_comment        varchar(200),
    news_departement    int foreign key(dep_id) references departement(dep_id)
);
Anayat
la source
Veuillez fournir quelques explications sur le schéma que vous avez fourni.
samabcde