A experiência conta muito, mas em termos de design de tabelas, você pode aprender muito sobre como os ORMs como o Hibernate e o Grails operam para ver por que eles fazem as coisas. Além do que, além do mais:
Mantenha diferentes tipos de dados separados - não armazene endereços na sua tabela de pedidos, vincule-os a um endereço em uma tabela de endereços separados, por exemplo.
Pessoalmente, gosto de ter uma chave substituta inteira ou longa em cada tabela (que contém dados, e não aquelas que vinculam tabelas diferentes, por exemplo, relacionamentos m: n) que é a chave principal.
Também gosto de ter uma coluna de carimbo de data e hora criada e modificada.
Verifique se todas as colunas que você faz "where column = val" em qualquer consulta têm um índice. Talvez não seja o índice mais perfeito do mundo para o tipo de dados, mas pelo menos um índice.
Configure suas chaves estrangeiras. Configure também as regras ON DELETE e ON MODIFY, quando relevantes, para cascatear ou definir nulo, dependendo da estrutura do seu objeto (portanto, você só precisa excluir uma vez na "cabeça" da árvore de objetos e todos os subobjetos desse objeto serão removido automaticamente).
Se você deseja modularizar seu código, modularize seu esquema de banco de dados - por exemplo, esta é a área "customers", esta é a área "orders" e esta é a área "products" e usa tabelas de junção / link entre eles, mesmo que sejam relações 1: n, e talvez duplique as informações importantes (por exemplo, duplique o nome do produto, código e preço na tabela order_details). Leia sobre normalização.
Outra pessoa recomendará exatamente o oposto para alguns ou todos os itens acima: p - nunca uma maneira verdadeira de fazer algumas coisas, eh!