#php #mysql #sql #database #database-design
#php #mysql #sql #База данных #база данных-дизайн
Вопрос:
На моем веб-сайте я создаю функцию счета-фактуры. Счет-фактура содержит статическую информацию: информацию о компании и информацию о получателе. Но в ней также есть динамическая информация: количество часов, описание, общая сумма и т. Д. Клиенты могут добавлять несколько строк с динамической информацией выше.
Теперь мой вопрос в том, как мне реализовать это в моей базе данных?
На данный момент у меня есть таблица под названием «счет-фактура» со столбцами, в которых будет вся приведенная выше информация. Но таким образом, строки будут содержать ненужную информацию, такую как информация о компании и получателе, которая фактически должна быть вставлена только один раз для каждого счета.
Как вы, ребята, думаете, мне придется это решать?
Я бы хотел избежать использования 2 таблиц, но если другого варианта нет, то я это сделаю.
Приветствия
Ответ №1:
Если вы хотите полностью реляционную базу данных, вам нужно будет создать вторую таблицу. Это будет содержать информацию о клиенте. Затем этот ключ становится внешним ключом в вашей таблице счетов, поэтому вам нужно сохранить информацию о клиенте только один раз. Это был бы рекомендуемый способ реализации чего-то подобного.
Другой способ (и я не рекомендую это) заключается в том, что вам нужно будет создать циклическую ссылку на «родительский» счет-фактуру (тот, в котором хранится информация о клиенте). Затем, каждый раз, когда вы создаете новую накладную, вам нужно будет вставлять этот идентификатор родительской записи, чтобы у вас был способ получить сохраненную информацию. Для всех других счетов для того же клиента вы просто оставите эту информацию пустой.
Комментарии:
1. Спасибо за ваш ответ. В итоге я использовал 2 таблицы, как вы сказали. Когда я опубликовал этот вопрос, я хотел уменьшить количество таблиц в моей базе данных, но иногда вам просто нужна дополнительная таблица.
Ответ №2:
Выберите оператор для базовой таблицы
Ваше желание иметь только одну таблицу неосведомлено и опрометчиво.
Каждая таблица содержит базовое утверждение о ситуации приложения. Строки, которые делают утверждение true, попадают в таблицу.
ivoice(i,c,...) // invoice [i] is to company [c] with ...
company(c,n,a,...) // company [c] has name [n] and address [a] ...
receiver(r,...) // receiver [r] ...
Таким образом, каждая присутствующая строка содержит истинное утверждение (или оно будет отсутствовать), а каждая отсутствующая строка содержит ложное утверждение (или оно будет присутствовать). Таким образом, вы можете думать о таблице как о создании операторов из существующих строк плюс NOTs операторов из отсутствующих строк. Вместе базовые таблицы описывают ситуацию в вашем приложении.
Ограничить ‘И’ в операторах базовой таблицы
Основная идея состоит в том, чтобы удалить большую часть AND из ваших операторов. Если оператор таблицы является И меньших операторов, то они всегда должны быть либо как:
(1) something AND-free about [k1],...
где каждая подстрока в столбцах k1, … уникальна в таблице и не содержит меньших подстрок или подобных:
(2) [c]=some_function_of_all_of(k1,...)
(Это называется «5-я нормальная форма».)
Зачем ограничивать ‘И’?
Потому что в противном случае в вашей таблице было бы проблемное утверждение, сделанное из одного из более простых, например:
blah [k1] blah [k2] AND blub [j1]
Когда «blah ZZ blah 88» имеет значение true или false, вам обычно придется помещать не одну, а несколько строк в или из этой таблицы, в соответствии с истинностью «blub [j1]» для каждого возможного значения j1. (Это называется аномалией обновления.)
Кроме того, вполне вероятно, что вы хотите сказать, что «бла-бла-бла 999» является истинным или ложным (в таблице или вне ее), не жалуясь на j1s. Но выбранная вами таблица не позволит вам. (Это называется неправильным дизайном.)
PS: для каждого запроса есть оператор
Каждое выражение запроса также имеет оператор. Значение запроса — это строки, которые делают его утверждение истинным. Объединение таблиц с помощью операторов отношений для создания запроса объединяет операторы с помощью логических операторов для создания его утверждения. ОБЪЕДИНЕНИЕ, ON и WHERE для таблиц делает И операторов, ОБЪЕДИНЕНИЕ таблиц делает ИЛИ операторов, SELECT делает, ЕСТЬ и т.д. Поэтому, когда вы запрашиваете, вы создаете более сложные операторы из операторов базовой таблицы.
// there is a name n,... where:
// invoice [i] is to company [c] and ...
// AND company [c] has name [n] and address [a] ...
SELECT i,c,a FROM company JOIN invoice ON company.c=invoice.c