Como criar relacionamentos no MySQL

96

Em sala de aula, estamos todos 'estudando' bancos de dados e todos estão usando o Access. Entediado com isso, estou tentando fazer o que o resto da classe está fazendo, mas com comandos SQL brutos com MySQL em vez de usar o Access.

Já consegui criar bancos de dados e tabelas, mas agora como faço a relação entre duas tabelas?

Se eu tiver minhas duas tabelas como esta:

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 )
)

e

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 )
)

Como faço para criar um 'relacionamento' entre as duas tabelas? Quero que cada conta seja 'atribuída' a um customer_id (para indicar quem é o proprietário).

Josh Hunt
fonte
48
"RECUSO-ME a estudar o Access, vou estudar um mecanismo de banco de dados REAL: MySQL" Esse é o espírito! Parabéns = D
Metafaniel
2
Observe que as restrições de chave estrangeira não implementam relacionamentos, elas implementam integridade. A associação entre account_id e customer_id na tabela de contas implementa o relacionamento entre as respectivas entidades.
reaanb
1
“Esse é o espírito!”, Contanto que seja mysql com InnoDB, não MyISAM. Além disso, o postgreqsl tem alguns recursos interessantes sobre o MySQL que vale a pena dar uma olhada.
jgmjgm

Respostas:

102

Se as tabelas forem innodb, você poderá criá-las assim:

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;

Você deve especificar que as tabelas são innodb porque o mecanismo myisam não suporta chave estrangeira. Procure aqui para mais informações.

Eric Hogue
fonte
Eu vi em um artigo, que não há necessidade de especificar a cláusula ENGINE = InnoDB se InnoDB for definido como o mecanismo de armazenamento padrão, pode verificar usando o comando (mysql> SELECT @@ default_storage_engine;)
Arun
80

como ehogue disse, coloque isso em seu CREATE TABLE

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

alternativamente, se você já criou a tabela, use um comando ALTER TABLE:

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

Uma boa maneira de começar a aprender esses comandos é usando MySQL GUI Tools , que oferece uma interface mais "visual" para trabalhar com seu banco de dados. O verdadeiro benefício disso (em relação ao método do Access) é que, depois de projetar sua tabela por meio da GUI, ele mostra o SQL que será executado e, portanto, você pode aprender com isso.

nickf
fonte
3
Sua resposta é a melhor solução
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).

Você tem que se perguntar se este é um relacionamento de 1 para 1 ou um de muitos relacionamento. Ou seja, cada conta tem um cliente e cada cliente tem uma conta. Ou haverá clientes sem contas. Sua pergunta implica o último.

Se você quiser ter um relacionamento estrito de 1 para 1, basta mesclar as duas tabelas.

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,
)

No outro caso, a maneira correta de criar um relacionamento entre duas tabelas é criar uma tabela de relacionamento.

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
}

Então, se você tiver um customer_id e quiser as informações da conta, junte-se às contas dos clientes e contas:

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

Por causa da indexação, isso será incrivelmente rápido.

Você também pode criar uma VIEW que oferece o efeito da tabela combinada de contas de clientes, mantendo-as separadas

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
fonte
1
Eu acho que você quis dizer ca.não ac.(3 lugares).
Vista elíptica de
você escreveu PRIMARY KEY (customer_id, account_id)sem vírgula depois
theonlygusti
11

Adicionando ao comentário de ehogue, você deve fazer o tamanho das chaves em ambas as tabelas corresponder. Ao invés de

customer_id INT( 4 ) NOT NULL ,

Faça

customer_id INT( 10 ) NOT NULL ,

e certifique-se de que sua coluna int na tabela de clientes também seja int (10).

Zak
fonte
7

Certos motores MySQL suportam chaves estrangeiras. Por exemplo, InnoDB pode estabelecer restrições baseadas em chaves estrangeiras. Se você tentar excluir uma entrada em uma tabela que possui dependentes em outra, a exclusão falhará.

Se você estiver usando um tipo de tabela no MySQL, como MyISAM, que não suporta chaves estrangeiras, você não vincula as tabelas em qualquer lugar, exceto seus diagramas e consultas.

Por exemplo, em uma consulta, você vincula duas tabelas em uma instrução select com uma junção:

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

Aqui estão alguns recursos que o ajudarão a começar: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase e http://code.tutsplus.com/articles/sql-for-beginners-part- 3 relacionamentos de banco de dados - net-8561

Além disso, como outros disseram, use uma GUI - tente baixar e instalar o Xampp (ou Wamp) que executa o software do servidor (Apache e mySQL) em seu computador. Então, quando você navegar para // localhost em um navegador, selecione PHPMyAdmin para começar a trabalhar com um banco de dados mySQL visualmente. Como mencionado acima, usei innoDB para permitir que você faça relacionamentos conforme solicitado. Facilita muito ver o que você está fazendo com as tabelas do banco de dados. Apenas lembre-se de PARAR os serviços Apache e mySQL quando terminar - eles podem abrir portas que podem expô-lo a ameaças de hackers / mal-intencionados.

user3659515
fonte
Se você configurar o apache e o mysql para atender apenas a solicitações locais, não será necessário interrompê-los. Além disso, os usuários devem ter pelo menos um firewall de software instalado ao instalar esses tipos de serviços. Com isso dito, muitos roteadores domésticos vêm com um firewall embutido, de forma que as portas não devem ser abertas de qualquer maneira, a menos que tenham sido abertas por alguém com acesso ao roteador.
Chris
1

Uma das regras que você deve saber é que a coluna da tabela à qual você deseja fazer referência deve ter o mesmo tipo de dados que A tabela de referência. 2 se você decidir usar o mysql, você terá que usar o InnoDB Engine porque de acordo com sua pergunta, esse é o mecanismo que suporta o que você deseja alcançar no mysql.

Abaixo está o código, tente embora as primeiras pessoas a responderem a essa pergunta, elas 100% forneceram ótimas respostas e, por favor, considere todas elas.

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
fonte
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
fonte
Forneça alguma explicação sobre o esquema fornecido.
samabcde