Uma boa especificação de banco de dados ajuda a reduzir a complexidade da implementação de software e a diminuir os custos de comunicação.
1. A lei de ferro de construir um armazém
- | Lei de ferro | Nível | comentário | Conjunto de caracteres | Use UTF-8. Se o emoji estiver armazenado, use utf8mb4 para armazenamento. | forçado |
| | Regras de seleção | Use utf8_general_ci | forçado | |
2. A lei de ferro da construção de mesas
- | Lei de ferro | Nível | comentário | exegese | Certifique-se de ter anotações de campo. | forçado |
| | codificar | Use UTF-8. Se o emoji estiver armazenado, use utf8mb4 para armazenamento. | forçado |
| | se o campo é conceitual | Ele deve ser nomeado com is_xx, e o tipo de dado é unsigned tinyint (1 sim, 0 não), por exemplo, is_deleted(1 deletar, 0 não excluído). | forçado | Qualquer corpo deve ser sem sinal se não for negativo | Nome da tabela, nome do campo | Apenas letras minúsculas, sublinhados ou números podem ser usados; É proibido começar com sublinhado ou número; Apenas números são proibidos entre dois pontos sublinhados; Desativar palavras reservadas; O uso de substantivos plurais é proibido nos nomes das tabelas. | forçado |
| | A nomeação do nome do banco de dados e do nome da tabela | O nome do banco de dados deve ser consistente com o nome da aplicação, e o nome da tabela deve ser nomeado com Name_Role de negócios da tabela. | forçado |
| | Nomeação de índices | O índice de chave primária usa pk_ nome de campo; Índice único com uk_ nome de campo; Índices normais usam idx_ nomes de campos. | forçado | pk_ é a chave primária; uk_ é uma tonalidade única; idx_ é o índice | Tipo decimal | O tipo de dado é decimal, e o uso de float e double é proibido, float e double têm perda de precisão, e se a faixa de dados armazenados exceder a faixa de decimal, recomenda-se dividir os dados em inteiros e decimais e armazená-los separadamente. | forçado |
| | Tipo Varchar | varchar é uma string variável longa, nenhum espaço de armazenamento é alocado antecipadamente, o comprimento não deve exceder 5000 caracteres; se o comprimento for maior que 5000, aplique texto (crie uma tabela separada, use a chave primária para corresponder, para evitar afetar a eficiência de indexação de outros campos). | forçado |
| | Devem haver três campos no nome da tabela | id (tipo de dado é bigint sem sinal, incremento de tabela única, tamanho do passo é 1), gmt_create, gmt_modified (tempo de criação ativa, tempo de atualização passiva, tipo de dado é datetime). | forçado |
| | Redundância de campo | Campos permitem redundância adequada, mas a consistência dos dados deve ser considerada, e campos redundantes devem ter 1) modificações pouco frequentes; 2) Não um campo super longo varchar, muito menos um campo de texto. | Recomendar |
| | Divida o banco de dados e as tabelas | A particionação é recomendada apenas quando o número de linhas em uma única tabela excede 5 milhões de linhas ou a capacidade de uma única tabela ultrapassa 2 GB. | Recomendar | |
Definir o comprimento adequado de armazenamento de caracteres não só economiza espaço em tabelas de banco de dados e armazenamento de índices, mas, mais importante, melhora a velocidade de recuperação.
3. Estabelecer uma lei de ferro índice
- | Lei de ferro | Nível | comentário | Índice único | Campos com características únicas no negócio, mesmo que sejam uma combinação de campos, devem ser indexados de forma única. Embora o índice único afete a velocidade da inserção, essa perda é desprezível, mas melhora significativamente a velocidade da consulta. Além disso, mesmo que a camada de aplicação tenha controle de verificação muito completo, desde que não haja um índice único, de acordo com a Lei de Murphy, inevitavelmente serão gerados dados sujos. | forçado |
| | Junte-se | Mais de três tabelas proíbem o joining, campos que exigem join, e os tipos de dados devem ser consistentes; Quando múltiplas tabelas estão associadas a consultas, certifique-se de que os campos associados precisem ter um índice. Mesmo que você tenha uma junção de tabela dupla, preste atenção à indexação de tabelas, desempenho em SQL. | forçado |
| | Varcharfield | O comprimento do índice deve ser especificado, e não há necessidade de indexar todos os campos, apenas determinar o comprimento do índice de acordo com a distinção real do texto. Comprimento e distinção do índice são um par de contradições; geralmente, para dados de tipo de string, índices com comprimento 20 terão um grau de distinção superior a 90%, que pode ser determinado pelo grau de distinção de count(distinct left(nome da coluna, comprimento do índice))/count(*). | forçado |
| | O desfoque é proibido na busca por páginas | A busca por página proíbe o desfoque ou desfoque total; se necessário, acesse o mecanismo de busca para resolver. Razão da proibição: O arquivo índice possui a propriedade de correspondência de prefixo mais à esquerda da B-Tree, e se o valor à esquerda não for determinado, então esse índice não pode ser usado. | forçado |
| | Ordene por | Se houver uma ordem por cenário, preste atenção à ordem do índice. O último campo de ordem por faz parte do índice combinado e é colocado ao final da ordem de combinação do índice para evitar file_sort e afetar o desempenho da consulta. Exemplo: onde a=? e b=? ordem por c; O índice deve ser construído como a_b_c; Contraexemplo: Se houver uma consulta por intervalo no índice, então a ordem do índice não pode ser utilizada, como onde a>10 ordena por b; Índice a_b não pode ser organizado. | Recomendar | |
4. Escrever regras de ferro SQL
- | Lei de ferro | Nível | comentário | contagem(*) | Não use count(nome da coluna) ou count(constant) no lugar de count(*), que é a sintaxe para a contagem padrão de linhas definida pelo SQL92, independente do banco de dados, e independente de NULL e não-NULL. count(*) conta linhas com valor NULL, enquanto count(nome da coluna) não conta linhas com essa coluna NULL. | forçado |
| | Conde (col distinto) | Conta o número de linhas únicas na coluna, exceto NULL. Note que contagem (distinto col1, col2), se uma das colunas for toda NULL, então retorna 0 mesmo que a outra coluna tenha um valor diferente. | forçado |
| | Sum(col) | Quando os valores de uma coluna são todos NULL, count(col) retorna 0, mas sum(col) retorna NULL, então você precisa estar atento a questões de NPE ao usar sum(). Problemas de NPE podem ser evitados das seguintes formas: selecionar if(isnull(sum(g)), 0, sum(g)) da tabela; | forçado |
| | isnull | Use isnull() para determinar se é um valor NULL. NULL é NULL comparado a qualquer valor. | forçado |
| | Lógica de consulta por paginação | Se a contagem for 0, ela deve ser retornada diretamente para evitar a execução da instrução de paginação subsequente. | forçado |
| | Teclas externas e cascatas | O uso de chaves estrangeiras e cascatas é proibido, e todos os conceitos de chave estrangeira devem ser resolvidos na camada de aplicação. Motivo: Chaves estrangeiras e cascatas não são adequadas para clusters distribuídos de alta concorrência, atualizações em cascata são fortes bloqueios, há risco de tempestades de atualizações de banco de dados e chaves estrangeiras afetam a velocidade de inserção do banco de dados. | forçado |
| | Procedimentos armazenados | Procedimentos armazenados são proibidos, e procedimentos armazenados são difíceis de depurar e escalar, além de não serem portáteis. | forçado |
| | Correção de dados | Ao corrigir dados (especialmente ao excluir ou modificar registros), selecione primeiro para evitar exclusão acidental, e execute a instrução update apenas após confirmar que está correta. | forçado |
| | em | Se não puder ser evitado, o número de elementos do conjunto após o in deve ser controlado dentro de 1000. | Recomendar |
| | Tabela truncada | É proibido usar a tabela truncada, que é mais rápida que a exclusão e consome menos recursos do sistema e log, mas truncar é livre de transações e não aciona gatilhos, o que pode causar acidentes, portanto, não use essa declaração no código de desenvolvimento. | referência |
|
5. A ORM mapeia leis de ferro
| - | Lei de ferro | Nível | comentário | Consulta de tabela | A lista de campos que são proibidos de usar * para consultas deve ser clara sobre quais campos são necessários. | forçado |
| | POJO | O atributo booleano da classe POJO não pode ser adicionado a is, enquanto o campo do banco de dados deve ser adicionado a is, exigindo mapeamento entre campos e atributos no resultMap. | forçado |
| | Parâmetros de retorno | É proibido usar resultClass como parâmetro de retorno, mesmo que todos os nomes dos atributos de classe correspondam aos campos do banco de dados um por um, eles precisam ser definidos; Por sua vez, cada tabela deve ter um atributo correspondente a ela. Motivo: Configure a relação de mapeamento para acoplar o campo à classe DO para facilitar a manutenção. | forçado |
| | Parâmetros de retorno | É proibido usar diretamente HashMap e HashTable como saída do conjunto de resultados da consulta. Motivo: O tipo de valor do atributo é incontrolável. | forçado |
| | sql.xml Configurar parâmetros | sql.xml Use #{}, #param# para parâmetros de configuração e não use ${}, pois ${} é propenso a injeção SQL. | forçado |
| | queryForList | O uso de queryForList (String statementName, int start, int size) que vem com o Mybatis é proibido. Razão: É implementado recuperando todos os registros da instrução SQL correspondente à statementName no banco de dados e, em seguida, usando o subList para obter um subconjunto de tamanho, start. | forçado |
| | Hora da atualização | Ao atualizar um registro de tabela de banco de dados, você deve atualizar o tempo de modificação do registro ao mesmo tempo. | forçado |
| | Atualizar registros de tabelas de banco de dados | Não escreva uma interface grande e completa de atualização de dados (passada como uma classe POJO). Ao executar SQL, não atualize campos inalterados devido ao armazenamento binlog propenso a erros, ineficiente e aumentado. | Recomendar |
| | @Transactional | @Transactional Não abuse das transações. As transações afetam o QPS do banco de dados. Além disso, onde você usa transações, é necessário considerar vários aspectos dos esquemas de rollback, incluindo rollback de cache, rollback de mecanismos de busca, compensação de mensagens, correção estatística, etc. | referência |
| | Tags SQL dinâmicas Mybatis | < compareValue em isEqual> é uma constante comparada ao valor do atributo, geralmente um número, indicando que a instrução SQL correspondente é executada quando igual; < isNotEmpty> indica que é executado quando não está vazio e não é nulo; < isNotNull> indica que é executado quando não é nulo. | referência | |
|