Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Tutorial SQL de chave primária – Como definir uma chave primária em um banco de dados


Toda grande história começa com uma crise de identidade. Luke, o grande Mestre Jedi, começa incerto - "Quem sou eu?" - e como eu poderia ser alguém importante? É preciso Yoda, aquele com a Força, para ensiná-lo a aproveitar seus poderes.

Hoje, deixe-me ser seu Yoda.

Começaremos com como escolher uma chave primária, combater uma crise de identidade e terminar com exemplos de código para criar uma chave primária em um banco de dados.

Como escolher uma chave primária


Você pode pensar que Luke é o único com uma crise de identidade, mas isso não é verdade. Ao criar um banco de dados, tudo está em crise de identidade. E é exatamente por isso que precisamos de chaves primárias:elas resolvem a crise. Eles nos dizem como encontrar todos.

Imagine que você é o governo e deseja identificar cada um de seus cidadãos digitalmente. Então, você cria esse banco de dados com tudo sobre eles:
First Name
Last Name
Passport Number

Você escolhe o número do passaporte como a chave primária - a identidade para todos. Você acha que isso é tudo que você precisa, já que o passaporte tem o endereço e tudo mais. Você sabe que os números dos passaportes são únicos, então você se sente bem e implementa esse sistema.

Então, alguns anos depois, você descobre uma verdade feia:o país inteiro está enfrentando uma crise de identidade.

Sempre que o passaporte de alguém expira, ele recebe um novo. Sua identidade muda. Outros sistemas continuam usando os números de passaportes antigos, então agora eles apontam para pessoas fantasmas.
Singularidade não é suficiente. O valor não deve mudar durante a vida útil da linha.

E então, você descobre que há algumas pessoas que nem têm passaporte. Você não pode inseri-los em seu sistema, pois as Chaves Primárias não podem ser NULL . Como você pode identificar alguém com um NULL chave?
Cada linha deve ter um identificador. NULLs não permitidos.

A próxima iteração significa encontrar um identificador que não mude ao longo do tempo e que todos tenham. Na Índia, isso está se tornando o Cartão Adhaar. Nos EUA, o Social Security Number.

Se você estiver criando um banco de dados, faça delas suas chaves primárias.

Às vezes, você não tem essa chave. Considere um país que ainda não possui um número de seguro social e deseja criar um registro digital de cada cidadão. Eles podem criar um novo SSN ou simplesmente aproveitar o poder dos bancos de dados e usar uma chave substituta.

Uma chave substituta não tem equivalente no mundo real. É apenas um número dentro de um banco de dados. Então, você tem esta tabela no novo país:
userID
First Name
Last Name
Passport Number

Os números de passaporte são únicos. Sempre que você quiser obter o identificador de um usuário, poderá obtê-lo através do Número do Passaporte.

O userID nunca muda. O número do passaporte pode mudar - mas é sempre único, para que você sempre tenha o usuário certo. O userID é um substituto para um Número de Seguro Social não existente neste país.
Curiosidade:O Número do Passaporte aqui também é uma Chave Candidata. Poderia ter sido a Chave Primária, se nunca mudasse. Esta é uma distinção lógica de negócios.

A principal conclusão é esta:Sempre que você escolher uma chave primária, pense em uma crise de identidade . É possível que alguém altere seu identificador no futuro? Podemos entrar em um estado com várias pessoas com o mesmo identificador?

Eu uso as pessoas como exemplo, porque torna a identidade mais clara - sabemos que cada pessoa deve ter uma identidade. Transfira esse pensamento para seus bancos de dados. Tudo tem uma identidade, e é exatamente por isso que você precisa de Chaves Primárias.
Observação:Às vezes, é possível e desejável usar várias colunas juntas como a chave primária. Esta é uma chave composta.

Agora vamos tentar definir Chaves Primárias com exemplos de código reais. Há duas coisas a fazer aqui:primeiro, você identificará a Chave Primária. Em seguida, você aprenderá a sintaxe para defini-lo em um banco de dados.

Um exemplo do mundo real


Digamos que você administre uma startup de transporte, muito parecida com a Flexport. Você tem pacotes que precisam ir de um lugar para outro e navios que os transportam. Além disso, você tem clientes que estão solicitando esses pacotes.

Você imagina que precisará de uma tabela para os clientes, uma para os pacotes e outra para o transporte, mostrando qual pacote está onde agora.

Pense em quais colunas você precisará e qual deve ser a Chave Primária. Se você fosse um engenheiro da Flexport, esta é uma questão real que você teria que descobrir. Nada é dado, tudo é descoberto no mundo real.

Dadas essas informações, eu projetaria essas tabelas assim:
Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time

Estamos perdendo as chaves primárias. Pense neles antes de continuar lendo.

Para o pacote, escolherei um substituto CódigoDoPacote. Eu poderia ter tentado listar todos os atributos da embalagem:peso, volume, densidade, idade. Eles identificariam exclusivamente o pacote, mas isso é muito difícil de fazer na prática. As pessoas não se importam com isso, apenas se importam com o pacote indo de um lugar para outro.

Portanto, faz sentido criar um número aleatório e usá-lo como ID. É exatamente por isso que você vê FedEx, UPS e todos os serviços de entrega usando códigos de barras e IDs. Essas são chaves substitutas geradas para rastrear pacotes.

Para o cliente, escolherei um substituto Identificação do Cliente. Aqui, novamente, eu tinha a opção de escolher, digamos, o CPF dos meus clientes. Mas, os clientes não querem compartilhar isso comigo apenas para que eu possa enviar algo para eles. Assim, geramos uma chave internamente, não informamos nossos clientes sobre essa chave e continuamos chamando-os de CustomerNo. 345681.
História divertida:Conheço algumas empresas onde eles expuseram este CustomerNo, e os clientes insistiram em ficar com o No. 1. Foi muito hilário - os engenheiros realmente tiveram que mudar seu código de front-end para:if (cust == 345681) print(1);

Para Transporte, escolherei um composto PackageID+Porta+hora. Isso é um pouco mais interessante. Eu poderia ter criado um substituto aqui também, e funcionaria tão bem.

Mas, aqui reside a magia da indexação. As Chaves Primárias obtêm um índice automaticamente, o que significa que a pesquisa é muito mais eficiente do que as Chaves Primárias.

Quando você estiver pesquisando nesse banco de dados, a maioria das consultas será no formato "onde está este pacote?". Em outras palavras, dado este PackageID, diga-me a porta e a hora em que está agora. Eu precisaria de um índice extra sobre PackageID se não o tivesse como parte da minha chave primária.

Isso soa bem? Etapa final, vamos definir essas 3 tabelas em SQL. A sintaxe varia um pouco com o banco de dados que você está usando.

Definindo chaves primárias no MySQL

CREATE TABLE customers
( customerID  INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  last_name   VARCHAR(30) NOT NULL,
  first_name  VARCHAR(25) NOT NULL,
  email		  VARCHAR(50) NOT NULL,
  address     VARCHAR(300)
);
CREATE TABLE packages
( packageID  INT(15) NOT NULL AUTO_INCREMENT,
  weight     DECIMAL (10, 2) NOT NULL,
  content    VARCHAR(50),
  CONSTRAINT packages_pk PRIMARY KEY (packageID) # An alternative way to above,
  # when you want to name the constraint as well.
);
CREATE TABLE transportation
( package 	INT(15) NOT NULL,
  port  	INT(15) NOT NULL,
  time	 	DATE NOT NULL,
  
  PRIMARY KEY (package, port, time),
  FOREIGN KEY package
  	REFERENCES packages(packageID)
	ON DELETE RESTRICT    # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.

);

Definindo chaves primárias no PostgreSQL

CREATE TABLE customers
( customerID  SERIAL NOT NULL PRIMARY KEY, # In PostgreSQL SERIAL is same as AUTO_INCREMENT - it adds 1 to every new row.
  last_name   VARCHAR(30) NOT NULL,
  first_name  VARCHAR(25) NOT NULL,
  address     TEXT,
  email		  VARCHAR(50) NOT NULL
);
CREATE TABLE packages
( packageID  SERIAL NOT NULL,
  weight     NUMERIC NOT NULL,
  content    TEXT,
  CONSTRAINT packages_pk PRIMARY KEY (packageID) # In PostgreSQL, this alternative way works too.
);
CREATE TABLE transportation
( package 	INTEGER NOT NULL,
  port  	INT(15) NOT NULL,
  time	 	DATE NOT NULL,
  
  PRIMARY KEY (package, port, time),
  
  FOREIGN KEY package
  	REFERENCES packages(packageID)
	ON DELETE RESTRICT    # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.

);

Não é muito diferente, não é? Depois de aprender o básico, você pode aplicá-lo a praticamente qualquer banco de dados com apenas uma rápida olhada na documentação. A chave é saber o que procurar!

Boa sorte, jovem padawan.

Gostou disso? Você também pode gostar Coisas que aprendi com um engenheiro de software sênior