[ad_1]

Banco de Dados da Biblioteca
foto por Twitter: @jankolario / Unsplash

Toda grande história começa com uma crise de identidade. Lucas, o grande mestre Jedi, começa inseguro – “Quem sou eu?” – e como eu poderia ser alguém importante? É preciso Yoda, aquele da 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 uma 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:

First NameLast NamePassport Number

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

Alguns anos depois, você descobre uma verdade feia: todo o país está enfrentando uma crise de identidade.

Sempre que o passaporte de alguém expira, ele recebe um novo. A identidade deles muda. Outros sistemas continuam usando os números antigos dos passaportes, e agora apontam para pessoas fantasmas.

Exclusividade não é suficiente. O valor não deve mudar ao longo da vida útil da linha.

E então, você encontrará algumas pessoas que nem sequer têm passaporte. Você não pode inseri-los no 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 significou encontrar um identificador que não muda ao longo do tempo e um que todos tenham. Na Índia, esse acabou sendo o cartão Adhaar. Nos EUA, o número do Seguro Social.

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

Às vezes, você não possui essa chave. Considere um país que ainda não possui um Número de Seguridade Social e deseja criar um registro digital de cada cidadão. Eles poderiam criar um novo SSN ou apenas 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:

userIDFirst NameLast NamePassport Number

Os números do passaporte são únicos. Sempre que você deseja obter o identificador para um usuário, pode 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 obtenha o usuário certo. O userID é um substituto para um número de segurança social inexistente neste país.

Curiosidade: O número do passaporte aqui também é uma chave de candidato. Poderia ter sido a Chave Primária, se nunca mudasse. Esta é uma distinção da lógica de negócios.

O principal argumento é este: Sempre que você escolher uma Chave Primária, pense em uma crise de identidade. É possível que alguém mude seu identificador no futuro? Podemos entrar em um estado com várias pessoas com o mesmo identificador?

Uso as pessoas como exemplo, porque isso torna a identidade mais clara – sabemos que toda 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.

Nota: À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 real. Há duas coisas a fazer aqui: primeiro, você identificará a Chave Primária. Em seguida, você aprenderá a sintaxe para defini-la em um banco de dados.

Um exemplo do mundo real

Digamos que você execute uma startup de remessa, como o 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 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, essa é uma pergunta real que você precisaria descobrir. Nada é dado, tudo é descoberto no mundo real.

Dada essa informação, eu projetaria essas tabelas da seguinte maneira:

Customers: first_name, last_name, email, address (for deliveries to their location)Packages: weight, contentTransportation: , Port, time

Faltam as chaves primárias. Pense neles antes de ler mais.


Para o pacote, eu vou escolher um substituto PackageID. Eu poderia ter tentado listar todos os atributos do pacote: 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 ir de um lugar para outro. Portanto, faz sentido criar um número aleatório e usá-lo como o ID. É exatamente por isso que você vê FedEx, UPS e todos os serviços de entrega usam códigos de barras e IDs. Essas são chaves substitutas geradas para rastrear pacotes.

Para o cliente, vou escolher um substituto Identificação do Cliente. Aqui, novamente, eu tive a opção de escolher, digamos o Número de Seguridade Social dos meus clientes. Mas, os clientes não querem compartilhar isso comigo, apenas para que eu possa enviar algo a 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 nas quais eles expuseram esse CustomerNo, e os clientes insistiram em obter o número 1. Foi muito hilário – os engenheiros realmente tiveram que alterar seu código de front-end para: if (cust == 345681) print(1);

Para o transporte, vou escolher um composto PackageID + Port + time. Isso é um pouco mais interessante. Eu poderia ter criado um substituto aqui também, e também funcionaria. Mas, aqui está a mágica da indexação. As Chaves Primárias obtêm um índice automaticamente, o que significa que a pesquisa é muito mais eficiente em relação às Chaves Primárias. Quando você está pesquisando nesse banco de dados, a maioria das consultas tem o formato “onde está esse pacote?”. Em outras palavras, dado esse PackageID, diga-me a porta e a hora em que está agora. Eu precisaria de um índice extra sobre o PackageID se não o tivesse como parte da minha Chave Primária.

Isso parece bom? Etapa final, vamos definir essas 3 tabelas no 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, é? Depois de entender o básico, você pode aplicá-lo a quase 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ê pode gostar também Coisas que aprendi com um engenheiro de software sênior

[ad_2]

Fonte