Best way to register two foreign keys in a table

Asked

Viewed 2,169 times

0

I have 3 tables, being them: personal, pesso_juridical and addressee.

Both the tebela pessoa_fisica, as for tebela pessoa_juridica use the table endereco. I would like to add two foreign keys in the table endereço. Being one linked to id of pessoa_fisica and another to id of pessoa_juridica. Thus, in case a record of pessoa_fisica or pessoa_juridica is deleted, the address will also be.

My problem is that Mysql does not allow me to register a record in the address table if there is no reference to foreign keys in the tables pessoa_fisica and pessoa_juridica.

Is there any way to treat this without creating two address tables (one for pessoa_fisica and another to pessoa_juridica)?

  • @Marconi there is different information in person and person. So this option is not feasible for me.

  • I would like to get an option where it is not necessary to create two address tables. Pq the address fields are equal for the two tables. So I don’t know if duplicating this table would be the best option!

  • I found interesting your question, here’s a great step of how to model your tables. Data Modeling - Part 06 (Generalizations / Specializations)

  • @Alan, there is, what you can do and add foreign keys so that the two can be optional. I’ll post an example of how to create this.

1 answer

1


You have to create in table 2 foreign keys can be null, Example of table create:

CREATE TABLE IF NOT EXISTS forum.pessoa_fisica (
  id INT NOT NULL AUTO_INCREMENT,
  nome VARCHAR(60) NOT NULL,
  cpf VARCHAR(15) NOT NULL,
  PRIMARY KEY (id))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS forum.pessoa_juridica (
  id INT NOT NULL AUTO_INCREMENT,
  razao_social VARCHAR(255) NOT NULL,
  cnpj VARCHAR(30) NOT NULL,
  PRIMARY KEY (id))
ENGINE = InnoDB; 



CREATE TABLE IF NOT EXISTS forum.endereco (
  id INT NOT NULL AUTO_INCREMENT,
  id_pessoa_juridica INT NULL,
  id_pessoa_fisica INT NULL,
  rua VARCHAR(255) NOT NULL,
  numero VARCHAR(10) NOT NULL,
  PRIMARY KEY (id),
  INDEX fk_endereco_pessoa_juridica_idx (id_pessoa_juridica ASC),
  INDEX fk_endereco_pessoa_fisica1_idx (id_pessoa_fisica ASC),
  CONSTRAINT fk_endereco_pessoa_juridica
    FOREIGN KEY (id_pessoa_juridica)
    REFERENCES forum.pessoa_juridica (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT fk_endereco_pessoa_fisica1
    FOREIGN KEY (id_pessoa_fisica)
    REFERENCES forum.pessoa_fisica (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;

Here I will insert in tables 1 fake data for each table

INSERT INTO pessoa_fisica(nome, cpf)VALUES('PessoaFisica', '00000000000');
INSERT INTO pessoa_juridica(razao_social, cnpj)VALUES('PessoaJuridica', '000000000000000');
INSERT INTO endereco(id_pessoa_fisica, rua, numero) VALUES(1,'Rua Pessoa Física', '1');
INSERT INTO endereco(id_pessoa_juridica, rua, numero) VALUES(1,'Rua Pessoa Juridica', '2');

To consult the addresses of the physical people and Uridicas we use the following querys:

/** CONSULTA ENDERECO PESSOA FISICA ID 1*/
SELECT
    pf.nome,
    pf.cpf,
    e.rua,
    e.numero
FROM pessoa_fisica pf
LEFT JOIN endereco e
ON e.id_pessoa_fisica = pf.id
WHERE pf.id = 1;


/** CONSULTA ENDERECO PESSOA JURIDICA ID 1*/
SELECT
    pj.razao_social,
    pj.cnpj,
    e.rua,
    e.numero
FROM pessoa_juridica pj
LEFT JOIN endereco e
ON e.id_pessoa_fisica = pj.id
WHERE pj.id = 1;

However it is not the best form of modeling, the personal and personal tables should be only 1 table where there would be reference with type person because it has many columns that can be equal, and if there was something more in some table, you would create other tables with this information, but it solves your problem.

  • My problem was exactly this when trying to do this way that you presented. By creating two foreign keys in the address table with CASCADE. They are created without any problem. However, when you register a physical person and try to register your address, Mysql will return an error. Because there is no referral of registered person. This was the initial form I tried to use and it did not work for me. I can solve the problem followed the template presented in the link q @Marconi passed. But still n had time to add the answer here.

  • This way that I posted will not give error because the fields can be null, if you want to run the example, you will see that there is no error. Abç

  • But the n problem is in the fields. When you add a foreign key to a table. You can only register a record in this table if there is at least 1 record registered in the table where the foreign key references. In my case, when registering a person_physica I have no registration registered in person_juridica and when I try to register the address it does not allow for n exist any registration registered in person_juridica.

  • You’re missing the point, come on, we have 3 personal, personal, and addressed tables (where you have two keys, physical and legal id_persons) TWO DISTINCT KEYS CAN BE NULL, so when I create an individual that will receive an id, and when I register the address I will pass this ID to the address table in the physical id_person field, if I do a legal will go to the personal id_legal field FOREIGN KEYS CAN BE NULL, in this case when it is physical, legal will be null and vice versa.

  • If you have questions create a test database and run the above commands for better understanding

  • I took the test here and you’re right. I ended up separating otherwise creating a fourth person table which left a little more organized some duplicated information between person_physique and person_juridica. But the way you did also solves the problem! value! ;)

  • Edit your answer so I can vote for it!

  • I edited, and yes, I even left an observation at the end, that sometimes it is more feasible to create an extra table, but for your problem this model solves

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.