MySQL'de nasıl ilişkiler oluşturulur


98

Sınıfta hepimiz veritabanları üzerinde çalışıyoruz ve herkes Access kullanıyor. Bundan sıkıldım, sınıfın geri kalanının yaptığını yapmaya çalışıyorum, ancak Access kullanmak yerine MySQL ile ham SQL komutları ile.

Veritabanları ve tablolar oluşturmayı başardım, ancak şimdi iki tablo arasında nasıl ilişki kurabilirim?

Bunun gibi iki masam varsa:

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

ve

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

İki tablo arasında nasıl bir 'ilişki' oluşturabilirim? Her hesaba bir müşteri kimliği 'atanmasını' istiyorum (kimin sahibi olduğunu belirtmek için).


49
"Access'i incelemeyi REDDEDİYORUM, GERÇEK bir veritabanı motoru üzerinde çalışacağım: MySQL" İşte ruh bu! Tebrikler = D
Metafaniel

2
Yabancı anahtar kısıtlamalarının ilişkileri uygulamadığını, bütünlüğü sağladığını unutmayın. Hesap tablosundaki account_id ve customer_id arasındaki ilişki, ilgili varlıklar arasındaki ilişkiyi uygular.
reaanb

1
MyISAM değil InnoDB ile mysql olduğu sürece "ruh budur!" Ayrıca postgreqsl, MySQL üzerinden bakmaya değer birkaç ilginç özelliğe sahiptir.
jgmjgm

Yanıtlar:


104

Tablolar innodb ise, bunu şu şekilde oluşturabilirsiniz:

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;

Myisam motoru yabancı anahtarı desteklemediği için tabloların innodb olduğunu belirtmelisiniz. Daha fazla bilgi için buraya bakın .


InnoDB varsayılan depolama motoru olarak tanımlanmışsa ENGINE = InnoDB cümlesini belirtmeye gerek olmadığını bir makalede gördüm, komutu kullanarak kontrol edebilirsiniz (mysql> SELECT @@ default_storage_engine;)
Arun

81

ehogue'un dediği gibi, bunu OLUŞTURMA TABLONUZA koyun

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

alternatif olarak, tabloyu zaten oluşturduysanız, bir ALTER TABLE komutu kullanın:

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

Bu komutları öğrenmeye başlamanın iyi bir yolu , veritabanınızla çalışmak için size daha "görsel" bir arayüz sağlayan MySQL GUI Araçlarını kullanmaktır . Bunun gerçek yararı (Access'in yöntemine göre), tablonuzu GUI aracılığıyla tasarladıktan sonra, çalışacağı SQL'i size göstermesi ve dolayısıyla bundan öğrenebilmenizdir.


3
Cevabınız en iyi çözüm
Omar

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

Kendinize bu 1'e 1 ilişki mi yoksa birçok ilişkiden 1 mi diye sormalısınız. Yani her hesabın bir müşterisi var mı ve her müşterinin bir hesabı var mı? Yoksa hesabı olmayan müşteriler mi olacak? Sorunuz ikincisini ima ediyor.

1'e 1 katı bir ilişki istiyorsanız, iki tabloyu birleştirmeniz yeterlidir.

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

Diğer durumda, iki tablo arasında bir ilişki oluşturmanın doğru yolu bir ilişki tablosu oluşturmaktır.

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
}

Sonra bir customer_id'niz varsa ve hesap bilgilerini istiyorsanız, müşteri hesaplarına ve hesaplarına katılırsınız:

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

İndeksleme nedeniyle, bu çok hızlı olacaktır.

Ayrıca, ayrı tutarken birleştirilmiş müşteri hesapları tablosunun etkisini veren bir GÖRÜNÜM oluşturabilirsiniz.

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;

1
Ne demek düşünüyorum ca.değil ac.(3 yerler).
eliptik görünüm

PRIMARY KEY (customer_id, account_id)ondan sonra virgül olmadan yazdın
theonlygusti

11

Ehogue tarafından yapılan açıklamaya ek olarak, her iki tablodaki anahtarların boyutunu da eşleştirmelisiniz. Ziyade

customer_id INT( 4 ) NOT NULL ,

Bunu yapmak

customer_id INT( 10 ) NOT NULL ,

ve müşteriler tablosundaki int sütununuzun da int (10) olduğundan emin olun.


7

Bazı MySQL motorları yabancı anahtarları destekler. Örneğin, InnoDB yabancı anahtarlara dayalı olarak kısıtlamalar oluşturabilir. Bir tablodaki diğerine bağımlı olan bir girişi silmeye çalışırsanız, silme işlemi başarısız olur.

MySQL'de yabancı anahtarları desteklemeyen MyISAM gibi bir tablo türü kullanıyorsanız, diyagramlarınız ve sorgularınız dışında tabloları hiçbir yere bağlamazsınız.

Örneğin, bir sorguda, bir select ifadesindeki iki tabloyu bir birleşimle bağlarsınız:

SELECT a, b from table1 LEFT JOIN table2 USING (common_field);

2

İşte başlamanıza yardımcı olacak birkaç kaynak: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase ve http://code.tutsplus.com/articles/sql-for-beginners-part- 3-veritabanı ilişkileri - net-8561

Ayrıca başkalarının da söylediği gibi, bir GUI kullanın - bilgisayarınızda sunucu yazılımı (Apache ve mySQL) çalıştıran Xampp (veya Wamp) indirmeyi ve yüklemeyi deneyin. Sonra bir tarayıcıda // localhost'a gittiğinizde, bir mySQL veritabanıyla görsel olarak çalışmaya başlamak için PHPMyAdmin'i seçin. Yukarıda belirtildiği gibi, istediğiniz gibi ilişkiler kurmanıza izin vermek için innoDB'yi kullandı. Veritabanı tablolarıyla ne yaptığınızı görmenizi kolaylaştırır. Bitirdiğinizde Apache ve mySQL hizmetlerini DURDURMAYI unutmayın - bunlar sizi korsanlık / kötü niyetli tehditlere maruz bırakabilecek bağlantı noktalarını açabilir.


Apache ve mysql'yi yalnızca yerel isteklere hizmet edecek şekilde ayarlarsanız, onları durdurmanıza gerek yoktur. Ayrıca, bu tür hizmetleri yüklüyorlarsa, hangi kullanıcıların en azından bir yazılım güvenlik duvarının yüklü olması gerekir. Bununla birlikte, birçok ev yönlendiricisi, içlerine yerleşik bir güvenlik duvarı ile birlikte gelir, bu nedenle, yönlendiriciye erişimi olan biri tarafından açılmadıkça bağlantı noktaları açılmamalıdır.
Chris

1

Bilmeniz gereken kurallardan biri, başvurmak istediğiniz tablo sütununun Referans tablosu ile aynı veri türünde olması gerektiğidir. 2 mysql kullanmaya karar verirseniz InnoDB Engine kullanmanız gerekir, çünkü sorunuza göre mysql'de elde etmek istediğiniz şeyi destekleyen motor budur.

Kod şu ki, bu soruyu ilk yanıtlayanlar% 100 harika yanıtlar vermiş olsa da, kodu deneyin.

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

Lütfen sağladığınız şema hakkında biraz açıklama yapın.
samabcde
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.