Я занимаюсь как объектно-ориентированным программированием, так и (в основном транзакционным, но немного OLAP) проектированием баз данных, и в моих обстоятельствах есть много повторяющихся тем (по крайней мере, с OLTP).
Практика нормализации 3nf помогает мне практиковать некоторый вариант принципа единой ответственности. Таблица должна представлять концепцию в вашей системе - и концепции должны относиться друг к другу так, чтобы они пытались имитировать реальность; например, если я создаю систему, в которой у Клиента может быть 0 или много действий, я создаю таблицу клиентов и таблицу действий. Таблица действий имеет отношение внешнего ключа к таблице Customer. Когда я создаю хранимые процедуры, я обязательно использую внешнее объединение, чтобы присоединиться к Клиенту и деятельности, потому что бизнес-требование, чтобы у Клиента могло быть 0 действий.
Я также не упускаю возможности для расширения, используя таблицы мостов (ссылок). Например, если бы я пытался представить бизнес-правило, в котором книга могла бы иметь неограниченное (переменное) число авторов, я бы создал таблицу книг, таблицу авторов и таблицу мостов / ссылок, которые имеют ссылки на внешние ключи для обоих Книга и Автор.
Кроме того, я использую суррогатные ключи во всех таблицах (как правило, автоматически увеличивающие столбцы идентификаторов, но, возможно, Guids - компромисс с guids в коде заключается в том, что они занимают больше места в памяти, чем простое целое число), и я избегаю полагаться на естественные ключи для своего поиск (кроме таблиц мостов и ссылок). По умолчанию я также создаю индексы для общих столбцов внешнего ключа и время от времени просматриваю хранимые процедуры / системные запросы для оптимизации стратегий индексирования. Другая стратегия индексирования, которую я использую, заключается в поиске мест в моем коде, где я собираю коллекцию на основе столбца поиска, и добавляю соответствующие индексы в столбцы поиска.