Campos comuns do MySQL e seus tipos de dados apropriados

111

Estou configurando um banco de dados MySQL muito pequeno que armazena nome, sobrenome, e-mail e número de telefone e estou lutando para encontrar o tipo de dados 'perfeito' para cada campo. Sei que não existe uma resposta perfeita, mas deve haver algum tipo de convenção comum para campos comumente usados ​​como esses. Por exemplo, eu determinei que um número de telefone não formatado dos EUA é muito grande para ser armazenado como um int não assinado, deve ser pelo menos um bigint.

Como tenho certeza de que outras pessoas provavelmente achariam isso útil, não quero restringir minha pergunta apenas aos campos que mencionei acima.

Quais tipos de dados são apropriados para campos de banco de dados comuns? Campos como número de telefone, email e endereço?

Enrico
fonte

Respostas:

71

Alguém vai postar uma resposta muito melhor do que essa, mas só queria deixar claro que pessoalmente eu nunca armazenaria um número de telefone em qualquer tipo de campo inteiro, principalmente porque:

  1. Você não precisa fazer nenhum tipo de aritmética com ele, e
  2. Mais cedo ou mais tarde, alguém vai tentar (fazer algo como) colocar colchetes em torno de seu código de área.

Em geral, porém, pareço usar quase exclusivamente:

  • INT (11) para qualquer coisa que seja um ID ou faça referência a outro ID
  • DATETIME para carimbos de hora
  • VARCHAR (255) para qualquer coisa com garantia de menos de 255 caracteres (títulos de página, nomes, etc)
  • TEXT para praticamente todo o resto.

Claro que há exceções, mas acho que isso cobre a maioria das eventualidades.

da5id
fonte
2
Além disso, os inteiros suportam apenas um valor de 2 bilhões. Isso é 2.000.000.000. O que realmente não é espaço suficiente quando você deseja armazenar números de telefone internacionais, completos com o código do país. Eu nem mesmo vejo como você poderia encontrar espaço suficiente para armazenar um número como 655-405-4055 (6.554.054.055)
Kibbee
29
Além disso, é simplesmente errado. Alguém muito mais sábio do que eu me disse quando eu estava começando isso (com banco de dados) só porque algo se parece com um número não significa que seja ou deva ser tratado como tal ...
da5id
14
Usar varchar (255) às cegas é uma má ideia. Aplique pelo menos algum esforço básico para adivinhar o comprimento.
Morgan Tocker de
4
@Morgan Tocker: é a melhor prática, qualquer coisa abaixo de 255 caracteres ocupará o mesmo espaço.
raveren
7
@Raveren: Isso é específico do mecanismo de armazenamento - e o armazenamento não é o único custo. A classificação de dados e tabelas temporárias (mecanismo de memória) usará a quantidade fixa.
Morgan Tocker,
44

Aqui estão alguns tipos de dados comuns que uso (embora não seja muito profissional):

| Column           | Data type     | Note
| ---------------- | ------------- | -------------------------------------
| id               | INTEGER       | AUTO_INCREMENT, UNSIGNED                                                          |  
| uuid             | CHAR(36)      | or CHAR(16) binary                                                                |  
| title            | VARCHAR(255)  |                                                                                   |  
| full name        | VARCHAR(70)   |                                                                                   |  
| gender           | TINYINT       | UNSIGNED                                                                          |  
| description      | TINYTEXT      | often may not be enough, use TEXT 
                                     instead          
| post body        | TEXT          |                                                                                   |  
| email            | VARCHAR(255)  |                                                                                   |  
| url              | VARCHAR(2083) | MySQL version < 5.0.3 - use TEXT                                                  |  
| salt             | CHAR(x)       | randomly generated string, usually of 
                                     fixed length (x)    
| digest (md5)     | CHAR(32)      |                                                                                   |  
| phone number     | VARCHAR(20)   |                                                                                   |  
| US zip code      | CHAR(5)       | Use CHAR(10) if you store extended 
                                     codes      
| US/Canada p.code | CHAR(6)       |                                                                                   |  
| file path        | VARCHAR(255)  |                                                                                   |  
| 5-star rating    | DECIMAL(3,2)  | UNSIGNED                                                                          |  
| price            | DECIMAL(10,2) | UNSIGNED                                                                          |  
| date (creation)  | DATE/DATETIME | usually displayed as initial date of 
                                     a post                                       |  
| date (tracking)  | TIMESTAMP     | can be used for tracking changes in a 
                                     post                                        |  
| tags, categories | TINYTEXT      | comma separated values *                                                          |  
| status           | TINYINT(1)    | 1  published, 0  unpublished,  You 
                                     can also use ENUM for human-readable 
                                     values
| json data        | JSON          | or LONGTEXT       
Yentsun
fonte
4
@yentsun - Os emails são, na verdade, apenas 254; leia os comentários à pergunta postada por Neil McGuigan
RustyTheBoyRobot
16

Na minha experiência, os campos de nome / sobrenome devem ter pelo menos 48 caracteres - há nomes de alguns países, como Malásia ou Índia, que são muito longos em sua forma completa.

Os números de telefone e códigos postais devem ser sempre tratados como texto, não como números. O motivo normal dado é que existem códigos postais que começam com 0 e, em alguns países, os números de telefone também podem começar com 0. Mas o verdadeiro motivo é que eles não são números - são identificadores que por acaso são inventados de dígitos numéricos (e isso ignorando países como o Canadá que têm letras em seus códigos postais). Portanto, armazene-os em um campo de texto.

No MySQL, você pode usar campos VARCHAR para este tipo de informação. Embora pareça preguiçoso, significa que você não precisa se preocupar muito com o tamanho mínimo correto.

staticsan
fonte
Para apoiar ainda mais seu comentário sobre códigos postais, em países como o Reino Unido ou Canadá, os códigos postais são alfanuméricos.
Andy Baird
Você pode precisar se preocupar com o tamanho mínimo correto stackoverflow.com/questions/262238/…
Rohit Banga
@iamrohitbanga Embora você esteja correto para dados bem definidos, para nomes VARCHAR(255)faz sentido.
staticsan
9

Como você vai lidar com dados de comprimento variável (nomes, endereços de e-mail), convém usar VARCHAR. A quantidade de espaço ocupada por um campo VARCHAR é de [field length]+ 1 bytes, até o comprimento máximo de 255, então eu não me preocuparia muito em tentar encontrar um tamanho perfeito. Dê uma olhada no que você imagina que pode ser o maior comprimento, dobre-o e defina-o como seu limite VARCHAR. Dito isto...:

Eu geralmente defino os campos de e-mail como VARCHAR (100) - ainda não tive nenhum problema com isso. Nomes que defini como VARCHAR (50).

Como os outros já disseram, números de telefone e CEPs não são realmente valores numéricos, são strings contendo os dígitos 0-9 (e às vezes mais!) E, portanto, você deve tratá-los como uma string. VARCHAR (20) deve ser suficiente.

Observe que se você armazenasse números de telefone como inteiros, muitos sistemas assumirão que um número começando com 0 é um número octal (base 8)! Portanto, o número de telefone perfeitamente válido "0731602412" seria colocado em seu banco de dados como o número decimal "124192010" !!

nickf
fonte
1

Estou fazendo quase a mesma coisa e aqui está o que fiz.

Usei tabelas separadas para nome, endereço, e-mail e números, cada uma com uma coluna NameID que é uma chave estrangeira em tudo, exceto na tabela Nome, na qual é a chave primária agrupada. Usei MainName e FirstName em vez de LastName e FirstName para permitir entradas de negócios, bem como entradas pessoais, mas você pode não precisar disso.

A coluna NameID chega a ser um smallint em todas as tabelas porque tenho quase certeza de que não farei mais do que 32.000 entradas. Quase todo o resto é varchar (n) variando de 20 a 200, dependendo do que você quer armazenar (aniversários, comentários, e-mails, nomes realmente longos). Isso realmente depende do tipo de material que você está armazenando.

A tabela de Números é onde eu me afasto disso. Eu o configurei para ter cinco colunas rotuladas NameID, Phone #, CountryCode, Extension e PhoneType. Já falei sobre NameID. O número do telefone é varchar (12) com uma restrição de verificação parecida com esta: CHECK (Phone # like '[0-9] [0-9] [0-9] - [0-9] [0-9] [0 -9] - [0-9] [0-9] [0-9] [0-9] '). Isso garante que apenas o que eu quero vá para o banco de dados e os dados permaneçam muito consistentes. Os códigos de extensão e país eu chamei de smallints anuláveis, mas eles podem ser varchar se você quiser. PhoneType é varchar (20) e não pode ser anulado.

Espero que isto ajude!

Thomas
fonte