In general, be parsimonious with auto-generated keys. If you need one for the user's convenience, OK, but you should still enforce the natural key.
For example, you have PurchaseOrder. It has a unique key, externally provided. use it. Adding your own auto-generated value adds complexity and nothing else.
Similarly, SalesOrderLineItem.Id is unique throughout the table. Wouldn't you rather see line 1, 2, 3 than 62783444, 62783445, 62783446? That makes the primary key SaleOrderID, LineItem (instead of Id). Same for PurchaseOrderLineItem, which then gains a key of PurchaseOrder, LineItem.
You mention "splitting" a few times; I take it you mean a given Sales quantity may be apportioned to more than one Purchase order and Shipping order. Resist the temptation (if it comes) to use a trigger to enforce the relationship that, say, the sum total shipped is not more than was ordered. That kind of question can be implemented in SQL, and should be, but not as a referential-integrity constraint. Write a stored procedure to verify the order is "in bounds", and call it from your application at the appropriate time. That will permit real-world anomalous situations such as lost shipments and botched orders.
Other than that, you seem to be shooting for 3NF, which is a good place to be. If you keep following the 1:n relationships to define tables and enforce constraints rigorously, you'll likely end up with a sound design.
Without knowing more about the business requirements, with the given structure you defined I would probably go with something like this:
Expense (Id, DetId, TypeId, Amount, Date, EmployeeId)
ExpenseType (Id, Name)
Where Expense.TypeId
is a foreign key constraint to ExpenseType.Id
. ExpenseType
could contain rows for daily or monthly expenses. This is scalable, as if down the road you have the requirement for weekly expenses, or yearly expenses (etc.) then this normalization will benefit. Expense.EmployeeId
would be a foreign key constraint to your employee table, and Expense.DetId
sounds like it'd be a foreign key constraint to another table that I can't seem to translate from the column name. If it is just details for each expense, no reason not to just put it directly in the Expense
table (provided a 1:1 relationship between expense and expense details). I may be missing a few columns, but I'm sure you get the idea.
Best Answer
The "typical" method for accomplishing this type of design is something like this:
You could use pivot functionality to show the data in a table format, similar to your example. In SQL Server this might look something like:
This is the code to create the tables, etc, if anyone is interested: