Дизайн и реализация базы данных в Laravel — автоматические приращения, привязанные к отдельным строкам, а не только к одной таблице

У меня есть вопрос, на который можно ответить либо теоретически, либо эмпирически, в зависимости от того, было ли это полностью достигнуто ранее или нет.

У меня есть веб-приложение, которое я создаю, которое может содержать несколько клиентов, каждый из которых имеет свои собственные отдельные наборы данных. Одной из конкретных функций этого программного обеспечения является выставление счетов.

При этом каждый создаваемый вами счет будет увеличиваться на 1, поэтому обычно мы применяем поле AUTO_INCREMENT к идентификатору. Проблема, однако, возникает, когда мы начинаем вводить несколько функций клиента.

Позвольте мне продемонстрировать проблему на примере:

Клиент А совершает свою первую продажу и создает для нее счет, который автоматически имеет идентификатор 1. К моменту обработки продажи он совершил вторую продажу. Когда он создает свой второй счет, он замечает, что что-то не так с нумерацией счетов. Его второй счет теперь имеет идентификатор 3.

Причина этого в том, что клиент Б, недавно зарегистрировавшись в системе, создал свою первую продажу с идентификатором 2. Теперь у обоих клиентов неправильная нумерация счетов, и это очень быстро стало неработоспособным решением.

Мне пришлось добавить таблицу с именем invoice_client_increments, которая, по сути, является связующим звеном между счетом-фактурой и клиентом, в котором хранится новое приращение. Хотя это работает, работать с ним очень грязно.

При создании счета я должен извлечь последнюю запись invoice_client_increments для этого клиента и добавить к ней одну, вставить другую и связать ее со счетом. Если кто-то удаляет счет-фактуру, это приращение теряется, и оно не будет вести себя как обычно приращения, вместо этого оно перезапишет удаленный при создании счета-фактуры.

Есть ли лучший способ спроектировать базу данных для этого и более простой способ реализовать это в Laravel, или я делаю это так, как это уже должно быть сделано? Это может быть скорее вопрос наилучшей практики, а не «Как мне это сделать?»... Спасибо за ваше время :)


person matthewc    schedule 17.08.2014    source источник
comment
Я не вижу проблемы, что не так с разными идентификаторами?   -  person Issam Zoli    schedule 17.08.2014
comment
Клиенты захотят, чтобы их системы выставления счетов начинались с 1 и не имели пробелов по юридическим причинам. Если бы было 300 клиентов и один создал свой первый счет как счет 1489, а второй как счет 5930, это не имело бы смысла и запутало клиента.   -  person matthewc    schedule 17.08.2014
comment
Я убрал тег php и добавил мультитенантность, что может помочь привлечь больше внимания экспертов по мультиарендности. Это не проблема php.   -  person Mike Sherrill 'Cat Recall'    schedule 17.08.2014


Ответы (3)


При этом каждый создаваемый вами счет будет увеличиваться на 1, поэтому обычно мы применяем поле AUTO_INCREMENT к идентификатору.

Администраторы баз данных не обычно этого не делают.

Финансовые приложения обычно должны учитывать каждый номер счета-фактуры. Автоматически увеличивающиеся идентификационные номера на всех платформах гарантированно будут иметь пробелы при определенных обстоятельствах (как правило, откат с одновременными операторами вставки). Вы не можете объяснить пробелы, просто сказав: «О, должно быть, произошел откат».

Есть два широких подхода к вашей проблеме.

  • Используйте метод Laravel или хранимую процедуру, чтобы вернуть номер следующего счета для данного клиента. Обратите особое внимание на уровни изоляции и блокировки транзакций.
  • Изменить архитектуру. Совместное использование таблиц — это один из видов многопользовательской архитектуры. Это не единственный вид, и часто это не лучший выбор. Когда вы читаете эту связанную статью, имейте в виду, что поведение базы данных MySQL больше похоже на схему SQL Server, чем на базу данных SQL Server.
person Mike Sherrill 'Cat Recall'    schedule 17.08.2014
comment
Второе решение имеет большую ценность и предлагает совершенно другой подход к проектированию базы данных. Беглый просмотр статьи открыл множество дверей, и я отвечу должным образом, как только прочитаю все и усвою, спасибо. - person matthewc; 17.08.2014

мой друг, посмотрите, вы можете создать такую ​​​​систему, как эта, один столбец будет автоматически увеличиваться, вам не нужно создавать другую таблицу cleint_increment, если вы этого не хотите. если вы хотите, вы можете подумать так

например, ваш автоматический приращение в порядке, но когда ваш клиент представляет продажу, его продажа должна увеличиться на единицу, и ваш номер счета может выглядеть так. incrementNo/CleintReference/CleintsaleNo.

что cleint продажи нет. добавляет 1 каждый раз, когда он отправляет свою продажу, она не начинается, когда он начал продажу, таким образом, вы будете знать, какая продажа какой клиент, и ваш клиент будет знать, сколько продаж он или она сделал сегодня.

person arif_suhail_123    schedule 17.08.2014

Если вы не нашли решение и еще не опоздали, вот что я сделал для одного приложения.

Я получал все заказы от этого конкретного клиента, подсчитывал их, а затем увеличивал это число на единицу, таким образом, вы всегда начинаете для каждого клиента счет с 0, а затем увеличиваете его на 1.

e.g.

$totalOrders = DB::table('orders')->where('client_id', $id)->count();'

DB::table('invoices')->insert(array('client_id' =>  $id, 'invoice_no' => ($totalOrders + 1)));

Я надеюсь, что это поможет вам :)

person lesandru    schedule 10.09.2014