Как создавать отношения в MySQL

98

В классе мы все «изучаем» базы данных, и все пользуются Access. Мне это надоело, и я пытаюсь делать то, что делает остальной класс, но с необработанными командами SQL с MySQL вместо использования Access.

Мне удалось создать базы данных и таблицы, но как теперь установить связь между двумя таблицами?

Если у меня есть две такие таблицы:

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

и

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

Как мне создать «связь» между двумя таблицами? Я хочу, чтобы каждой учетной записи был «назначен» один customer_id (чтобы указать, кому он принадлежит).

Джош Хант
источник
49
«Я ОТКАЗЫВАюсь изучать Access, я буду изучать НАСТОЯЩИЙ движок базы данных: MySQL» Это дух! Поздравления = D
Метафаниэль
2
Обратите внимание, что ограничения внешнего ключа не реализуют отношения, они реализуют целостность. Связь между account_id и customer_id в таблице учетных записей реализует связь между соответствующими объектами.
reaanb 05
1
«Это дух!», Если это mysql с InnoDB, а не MyISAM. Также postgreqsl имеет несколько интересных функций по сравнению с MySQL, на которые стоит обратить внимание.
jgmjgm

Ответы:

104

Если таблицы innodb, вы можете создать их так:

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;

Вы должны указать, что таблицы являются innodb, потому что механизм myisam не поддерживает внешний ключ. Смотрите здесь для получения дополнительной информации.

Эрик Хог
источник
Я видел в статье, что нет необходимости указывать предложение ENGINE = InnoDB, если InnoDB определен как механизм хранения по умолчанию, можно проверить с помощью команды (mysql> SELECT @@ default_storage_engine;)
Арун
80

как сказал ehogue, поместите это в свою СОЗДАТЬ ТАБЛИЦУ

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

в качестве альтернативы, если у вас уже есть таблица, используйте команду ALTER TABLE:

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

Хороший способ начать изучение этих команд - использовать инструменты графического интерфейса пользователя MySQL , которые дают вам более «визуальный» интерфейс для работы с вашей базой данных. Реальное преимущество этого (по сравнению с методом Access) заключается в том, что после создания таблицы через графический интерфейс он показывает SQL, который будет запускаться, и, следовательно, вы можете извлечь из этого урок.

Nickf
источник
3
Ваш ответ - лучшее решение
Омар
15
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).

Вы должны спросить себя, это отношения 1 к 1 или отношения 1 из многих. То есть, у каждой учетной записи есть клиент и у каждого клиента есть учетная запись. Или будут клиенты без счетов. Ваш вопрос подразумевает последнее.

Если вы хотите иметь строгое соотношение 1 к 1, просто объедините две таблицы.

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

В другом случае правильный способ создать связь между двумя таблицами - это создать таблицу отношений.

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
}

Затем, если у вас есть customer_id и вам нужна информация об учетной записи, вы присоединяетесь к своим клиентам и учетным записям:

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

Благодаря индексации это будет невероятно быстро.

Вы также можете создать VIEW, который даст вам эффект объединенной таблицы customersaccounts, сохраняя их раздельными

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
источник
1
Я думаю, вы имели в виду ca.нет ac.(3 места).
Эллиптический вид
вы написали PRIMARY KEY (customer_id, account_id)после него без запятой
theonlygusti
11

Добавляя к комментарию ehogue, вы должны сделать так, чтобы размеры ключей в обеих таблицах совпадали. Скорее, чем

customer_id INT( 4 ) NOT NULL ,

сделай это

customer_id INT( 10 ) NOT NULL ,

и убедитесь, что ваш столбец int в таблице клиентов также имеет значение int (10).

Зак
источник
7

Некоторые механизмы MySQL поддерживают внешние ключи. Например, InnoDB может устанавливать ограничения на основе внешних ключей. Если вы попытаетесь удалить запись в одной таблице, которая имеет иждивенцев в другой, удаление не удастся.

Если вы используете в MySQL тип таблицы, такой как MyISAM, который не поддерживает внешние ключи, вы не связываете таблицы нигде, кроме ваших диаграмм и запросов.

Например, в запросе вы связываете две таблицы в операторе выбора с помощью соединения:

SELECT a, b from table1 LEFT JOIN table2 USING (common_field);
Гэри Ричардсон
источник
2

Вот несколько ресурсов, которые помогут начать работу: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase и http://code.tutsplus.com/articles/sql-for-beginners-part- 3 отношения базы данных - net-8561

Также, как говорили другие, используйте графический интерфейс - попробуйте загрузить и установить Xampp (или Wamp), который запускает серверное программное обеспечение (Apache и mySQL) на вашем компьютере. Затем, когда вы перейдете к // localhost в браузере, выберите PHPMyAdmin, чтобы начать визуальную работу с базой данных mySQL. Как упоминалось выше, используется innoDB, чтобы вы могли устанавливать отношения по вашему запросу. Делает кучи проще увидеть, что вы делаете с таблицами базы данных. Просто не забудьте ОСТАНОВИТЬ службы Apache и mySQL по завершении - они могут открыть порты, которые могут подвергнуть вас взлому / вредоносным угрозам.

user3659515
источник
Если вы настроили apache и mysql для обслуживания только локальных запросов, вам не нужно останавливать их. Кроме того, у каких пользователей должен быть установлен, по крайней мере, программный брандмауэр при установке такого рода служб. С учетом сказанного, многие домашние маршрутизаторы поставляются со встроенным межсетевым экраном, поэтому порты в любом случае не должны быть открыты, если они не были открыты кем-то, у кого есть доступ к маршрутизатору.
Крис
1

Одно из правил, которое вы должны знать, - это то, что столбец таблицы, на который вы хотите сослаться, должен иметь тот же тип данных, что и ссылочная таблица. 2, если вы решите использовать mysql, вам необходимо использовать InnoDB Engine, потому что, согласно вашему вопросу, это движок, который поддерживает то, что вы хотите достичь в mysql.

Ниже приведен код, попробуйте его, хотя первые люди, ответившие на этот вопрос, на 100% дали отличные ответы и, пожалуйста, рассмотрите их все.

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; 
Муса
источник
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)
);
Анаят
источник
Пожалуйста, объясните предоставленную вами схему.
samabcde