mysql relationships

0

I have a small problem and I have doubts. Taking this text as an example:

"client contains the establishment, which in turn contains the lots"

My intent is this:

create table lotes (
id_lote int auto_increment primary key,
desc_lote varchar(50) not null
) ENGINE=InnoDB;

create table establecimientos(
id_establecimiento int auto_increment primary key,
desc_establecimiento varchar(50) not null,
id_lote int not null,
foreign key fk_id_lote(id_lote) references lotes(id_lote)
on update cascade
on delete restrict
) ENGINE=InnoDB;

create table clientes(
id_cliente int auto_increment primary key,
desc_cliente varchar(50) not null,
id_establecimiento int not null,
foreign key fk_id_establecimiento(id_establecimiento) 
references establecimientos(id_establecimiento)
on update cascade
on delete restrict
) ENGINE=InnoDB;

I insert a lot, an establishment, a client and everything is fine. I insert another establishment and try to add it to the same client, and it tells me duplicate key.

My question is if I have the pks well, I think that in clients, the pk should be id_client and set_id and at the same time id_establecliento is fk. Since a client can contain many establishments. Same with lots and establishments? I am right?

Thank you very much

    
asked by GAL 29.04.2017 в 17:44
source

1 answer

1

Your scheme will work fine, as long as you do not repeat the id_cliente in the insert.

Now, if in table clientes there should be repeated rows with the same id_cliente and the same client can have several associated establishments, you will need a third table that relates clients and establishments . That way in the table clientes you will have only the data of the client: id, name, telephone, etc and in the table that you will be able to call clientes-departamentos you will have several id of clients repeated and each one with its corresponding% id_departamento .

In this example, the last query INSERT accepts the same department, but for different clients, if the relationship is one to one the design of the table can be as you have it now, but if the relationship is many to many , that is, that in a department there may be several clients and / or vice versa, it is better to have a third table containing only two columns id_cliente, id_departamento and the primary key would be the combination of both columns, to avoid repeated data that will make your BD grow unnecessarily and make it slower, more difficult to consult, manage, maintain ...

For this case, I propose that you make your scheme as explained in the last section, entitled PROPOSED EXAMPLE .

SQL Fiddle

MySQL 5.6 Schema Setup :

create table lotes (
id_lote int auto_increment primary key,
desc_lote varchar(50) not null
) ENGINE=InnoDB;

INSERT INTO lotes (id_lote, desc_lote) VALUES (1,"desc1");

create table establecimientos(
id_establecimiento int auto_increment primary key,
desc_establecimiento varchar(50) not null,
id_lote int not null,
foreign key fk_id_lote(id_lote) references lotes(id_lote)
on update cascade
on delete restrict
) ENGINE=InnoDB;

INSERT INTO establecimientos 
(id_establecimiento,desc_establecimiento,id_lote)
VALUES (1,"desc est 1",1), (2,"desc est 2",1);



create table clientes(
id_cliente int auto_increment primary key,
desc_cliente varchar(50) not null,
id_establecimiento int not null,
foreign key fk_id_establecimiento(id_establecimiento) 
references establecimientos(id_establecimiento)
on update cascade
on delete restrict
) ENGINE=InnoDB;

INSERT INTO clientes (id_cliente,desc_cliente,id_establecimiento)
VALUES
(1,"desc cliente 1", 1),
(2,"desc cliente 2", 2);

Query 1 :

SELECT * FROM clientes

Results :

| id_cliente |   desc_cliente | id_establecimiento |
|------------|----------------|--------------------|
|          1 | desc cliente 1 |                  1 |
|          2 | desc cliente 2 |                  2 |

PROPOSED EXAMPLE

See this example with an associative table. Here you can repeat in the table cliente_establecimiento the field id_cliente controlling that there is not twice the same establishment-client, establishing in that table a pk composed of the fields that are foreign key of each table of the relation.

Then you do the query with JOINS , as shown in the example, or with any other of the existing JOIN types, according to your needs.

SQL Fiddle

MySQL 5.6 Schema Setup :

create table lotes (
id_lote int auto_increment primary key,
desc_lote varchar(50) not null
) ENGINE=InnoDB;

INSERT INTO lotes (id_lote, desc_lote) VALUES (1,"desc1");

create table establecimientos(
id_establecimiento int auto_increment primary key,
desc_establecimiento varchar(50) not null,
id_lote int not null,
foreign key fk_id_lote(id_lote) references lotes(id_lote)
on update cascade
on delete restrict
) ENGINE=InnoDB;

INSERT INTO establecimientos 
(id_establecimiento,desc_establecimiento,id_lote)
VALUES 
(1,"desc est 1",1), 
(2,"desc est 2",1),
(3,"desc est 3",1);

create table clientes(
id_cliente int auto_increment primary key, desc_cliente varchar(50) not null,
id_establecimiento int not null,
foreign key fk_id_establecimiento(id_establecimiento) 
references establecimientos(id_establecimiento)
on update cascade
on delete restrict
) ENGINE=InnoDB;

INSERT INTO clientes (id_cliente,desc_cliente,id_establecimiento)
VALUES
(1,"desc cliente 1", 1),
(2,"desc cliente 2", 2);

create table clientes_establecimientos(
  id_cliente int,
  id_establecimiento int,
  primary key(id_cliente,id_establecimiento)
 )ENGINE=InnoDB;

 INSERT INTO clientes_establecimientos(id_cliente,id_establecimiento)
 VALUES
 (1,1),
 (1,2),
 (2,1),
 (2,3);

Query 1 :

SELECT c.id_cliente,  c.desc_cliente, e.id_establecimiento 
FROM clientes_establecimientos ce
  LEFT JOIN clientes c 
    ON ce.id_cliente = c.id_cliente
  LEFT JOIN establecimientos e
    ON ce.id_establecimiento = e.id_establecimiento

Results :

| id_cliente |   desc_cliente | id_establecimiento |
|------------|----------------|--------------------|
|          1 | desc cliente 1 |                  1 |
|          1 | desc cliente 1 |                  2 |
|          2 | desc cliente 2 |                  1 |
|          2 | desc cliente 2 |                  3 |
    
answered by 29.04.2017 / 17:57
source