I have been given an assignment to complete the following task:
I will be using C# and Sql server to solve the above. However i need an heads up on how many tables i will need since i am completely new to this. I have given this a try, if someone can solve my query its fine or can give me a better alternate solution altogether.
This is what i have tried uptill now.
I have made 3 tables uptill now as shown in image below:
Now if you notice in the second image i could make Order Number applicable only for one party. However, the issue i am still facing is that when one Party Orders more than one type of Product i will have to generate 2 PO Numbers in the Orders Table.
What is the solution to my issue here? How do i Normalize it further?
P.S. This might sound like a simple question as a simple question because this is my first attempt on Normalization.
Maybe you can use this design. Observe below that there is only 1 PO number per party per order. This assumes you want to manually supply the PO Number; otherwise, you can use the OrderID as a convenient autogenerated PO Number.
I would suggest adding another table called "Orders". This table will contain the information that will be the same for the entire order, such as PONumber, PODate, RefDate, PartyID. Then your OrdersDetail table will contain the information for each product ordered, such as ProductId, Quantity, Rate, Amount, OrderId (FK into the new Order table).
Also, don't make all the data types Text. Consider using a data type appropriate for the information being stored. I would also consider either not including Amount or making it a calculated field since it is calculated from other information in the same record (Quantity * Rate).
Further you may consider using a different value other then PONumber as the primary key. As a general rule the primary key would have no other purpose other then internally identifying record. I would suggest adding an OrderDetailsId and make that the primary key.
Edit: (I have added additional information to answer Lohits question below)
If I understand what you are stating in your question, the Party can have multiple Orders; on each order the party can purchase multiple products. Therefore there would be a one-to-many relationship between PartyDetails and Order, and a one-to-may relationship between Order and OrderDetail; and a one-to-one relationship between ProductDetails and OrderDetails. The Party table stores the information about the person purchasing the order. The Order table stores the information about each order the person places. The OrderDetails stores the information about each product the person purchases for each order. And the ProductDetails table stores a list of all products.
Here is a diagram of the data structure as I see it....Mind you it does not have every detail in it. But hopefully it will give you enough to get started.
4 tables:
Partyinformation: id, name, address
Productinformation: id, name, price
Orderinformation: id: dates etc
Orderline: orderID, ProductID, Amount
where orderID and ProductID are the foreignkeys into productinformation and orderinformation
Adding products to the (created) order just involves adding an productID and OrderID into [orderline] incrementing the amount when the same product is entered twice.
Related
In the app there should be a functionality for the user to reset orderNumber whenever needed. We are using SQL Server for db, .NET Core, Entity Framework, etc. I was wondering what is the most elegant way to achieve this?
Thought about making orderNumber int, identity(1,1), and I've searched for DBCC CHECKIDENT('tableName', RESEED, 0), but the latter introduces some permissions concerns (the user has to own the schema, be sysadmin, etc.).
EDIT: orderNumber is NOT a primary key, and duplicate values are not the problem. We should just let the user (once a year probably) reset the numbering of their orders to start from 1 again..
Any advice?
An identity column is used to auto-generate incremental values, so if you're relying on this column as the primary key or some unique identifer for rows, updating this can cause issues with duplicates.
It's difficult to recommend the best solution without knowing more about your use case, but I would consider (1) if this orderNumber should be the PK or would some surrogate key like (customerId, locationId, date) makes sense and allows you to more freely update orderNumber without impacts on data integrity, or (2) if keeping orderNumber as an identity make sense, but you could build a data model or table that maps multiple rows in this table to the same "order" allowing you to maintain the key on this base table.
It seems that orderNumber is a business layer concern - therefore I recommend a non-SQL solution. You need C# code that generates the number for storage in your "Order" entity. I wouldn't use IDENTITY() to implement/solve this.
The customer isn't going to reset anything in the DB, your code will do this. You need a "take a number" service in your business layer and a place in the UI to reset it (presumable Per Customer).
Sql Server has Sequence. My only concern regarding using it is partitioning per customer (an assumed requirement). Will you have multiple customers? If so, you probably can't have a single number generator. Hence why I suggest a C# implementation (sure, you'll want to save the state as numbers are handed out).
Identity should not be used in the way you're suggesting. Presumably you don't want a customer to get two different orders with the same order number (i.e., order number is unique within customer). If you don't care if customers get discontinuous order numbers, then you can use a sequence, but if you want continuous order numbers, then you would need to create an separate sequence for each customer, which is not a good solution either. I suggest you set the order number to max([order number]) over(partition by [customer id]) + 1 on the insert. That will automatically give you the next order number for a particular customer.
I want to stores many different products in my database(as well as in one table). With help of inheritance (Table per Concrete Type) ,i am keeping all common fields(date,customer,orderID) in parent table and made one child table for one product .
one child table => it holds many different product with same and different fields
ProductOne = {A,B,**C**}
ProductTwo = {A,B,**D**}
ProductThree ={A,B,**F**}
Now i made TableAllProduct and Field of tables are {A,B,C,D,F}
To reason to select this design ,because i am thinking about my future new product ,For example if we got new product with these exist fields{A,B,C,D,F} ,so we should able to store new product data in TableAllProduct table without any software upgrade (instead create new table as per Inheritance approach which required new code)
TableAllProduct can hold three different product ProductOne = {A,B,C} ProductTwo = {A,B,D} ProductThree ={A,B,F}
Next step is stores Data in TableAllProduct
As per given scenario, ProductOne and ProductTwo have common field {A,B} But A field stores data from ProductOne as well as for ProductTwo
ProductOne have following option=={data__A_1,data__A_2 ,data__A_3}
ProductTwo have following option =={data__B_1,data__B_2 }
which i brings from other table (Manny to Manny)
Here we breaks rules of RDBMS ,Because I need multiple foreign key at one column ,But RDBMS doesn't supports , To delete/edit of foreign key responsibilities/function can done with DELETE_trigger(which will check record in Category table )
In this way , i can stores multiple product in table for now and future.
What is disadvantage of this approach ?
Is there any other possibilities solutions to solve this problem with better way .(I know about Entity–attribute–value model ,but in our situation ,product doesn't not changes daily /weekly bases and EVA is too complex to maintain).Thanks
You need to normalize your data.
The model you've described can work. You need to have the AllProducts table only contain the attributes(columns) in common for all of the products. Attributes like name and SKU, and maybe a reference to the vendor/supplier.
Once you have identified the common attributes, the remaining attributes can be moved into a table specific to each product. The SpecificProduct table can use the PK of the AllProducts table as a PK and FK. Every record in SpecificProduct will also have a record in the AllProducts table. The complete data for a specific product consists of the attributes from the AllProducts table joined to the columns for the specific product table.
This strategy helps to keep the AllProducts table width small when a varied subset of attributes relates to a small subset of the records in the table. By reusing the AllProducts PK as the PK/FK of the specific products table, you ensure joins performance will be good as well.
I am creating a billing software. I have created a database having 4 tables.
Category_Master
Product_Master
Customer_Master
Order_Details.
I am confused at creating rows in Order_Details. The reason is that, if a customer purchases 10 different items, then each items ProductCode should also be added to the Order_Details table.
So the thing is that do i need to create rows for each and every products or is their any other way to represent all ProductCode in a single cell.
I would recommend you to slit your Order_Details into two tables:
OrderProduct
OrderID | ProductCode
Order_Details
OrderID | OtherParameter
Each product of the order should be a new row in OrderProduct table. This structure will allow you to store order details separate from Products, connected with this order. The OrderProduct table would contain only links of your products with the orders in relation of many to many. Joining of these tables would allow you to make any required Select queries.
You need to create rows. Although there are alternatives that are technically possible, all of them are incredibly bad design and an uneducated hack at best.
I would also suggest you to create one more table (Order_Products) to manage the products ordered under one order, So that you will be able to easily track the products ordered under one order. Managing multiple values using a single cell can be used if the multiple values are of a constant size, such as days of a week which can be managed by using a binary field, But in your case the number of products is a variable and so i prefer using another table for doing the same.
Thank you.
I've got a logic-oriented issue, I think. I'm restructuring the database on my site to make it useful to the end user, and it's looking like this: I've got a list of seven products available, and each of them have an id of 1-7. I've got a submission table with an auto-incremented Id property (SubmissionId) to identify each unique submission, which may have multiple products (for example, a new customer may submit an add product form with EPL, Crime Fidelity, and Fiduciary), but not redundant products (can't have EPL and another EPL). I need to be able to link the product Id's to each submission in a workable way so that I can call it up to display the relevant information when a user calls up the submission to review it (basically like looking at their shopping cart). Obviously it's not feasible to create a table with all the possible iterations of 1-7 when there aren't necessarily 7 digits in the final count (because otherwise there would only be 49), so I was wondering if there was a way to combine each product id into a string, or something like it, insert that number into the ProductId column of the Submission table, and then use a SELECT WHERE LIKE statement to call up all the products associated with that particular SubmissionId?
For example, a user submits a new form, and the database autoincrements the value for column SubmissionId as 8. Then they add four products; EPL, Crime Fidelity, Fiduciary and Professional D&O. Those products have respective values of 1,3,4 and 6 in the column "ProductId" in the Product table. The collective ProductId value to be inserted into the Submission table would be 1346, and the logic to display the data associated with SubmissionId 8 would have a switch case statement looping through that ProductId to see if it contained each of the numbers 1-7 using the SELECT WHERE ProductId is LIKE (number), and then displaying the data from the relevant cases. How would I get the "1346" value to insert into the Submission table's ProductId column?
You should add a table that would link Product with Submission, eg. table S2P { Id, ProductId, SubmissionId } (I can't come up with better name). This is standard way to implement many to many relationship.
Check this link: http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php or google for many to many relationship to get more information.
Applicaiton is single user, 1-tier(1 pc), database SqlCE. DataService layer will be (I think) : Repository returning domain objects and quering database with LinqToSql (dbml). There are obviously a lot more columns, this is simplified view.
LogTime in separate table: http://i53.tinypic.com/9h8cb4.png
LogTime in ItemTimeLog table (as Time): http://i51.tinypic.com/4dvv4.png
alt text http://i53.tinypic.com/9h8cb4.png
This is my first attempt of creating a >2 tables database. I think the table schema makes sense, but I need some reassurance or critics. Because the table relations looks quite scary to be honest. I'm hoping you could;
Look at the table schema and respond if there are clear signs of troubles or errors that you spot right away.. And if you have time,
Look at Program Summary/Questions, and see if the table layout makes makes sense to those points.
Please be brutal, I will try to defend :)
Program summary:
a) A set of categories, each having a set of strategies (1:m)
b) Each day a number of items will be produced. And each strategy MAY reference it.
(So there can be 50 items, and a strategy may reference 23 of them)
c) An item can be referenced by more than one strategy. So I think it's an m:m relation.
d) Status values will be logged at fixed time-fractions through the day, for:
- .... each Strategy.....each StrategyItem....each item
e) An action on an item may be executed by a strategy that reference it.
- This is logged as ItemAction (Could have called it StrategyItemAction)
User Requsts
b) -> e) described the main activity mode of the program. To work with only today's DayLog , for each category. 2nd priority activity is retrieval of history, which typically will be From all categories, from day x to day y; Get all StrategyDailyLog.
Questions
First, does the overall layout look sound? I'm worried to see that there are so many relationships in all directions, connecting everything. Is this normal, or does it look like trouble?
StrategyItem is made to represent an m:m relationship. Is it correct as I noted 1:m / 1:1 (marked red) ?
StrategyItemTimeLog and ItemTimeLog; Logs values that both need to be retrieved together, when retreiving a StrategyItem. Reason I separated is that the first one is strategy-specific, and several strategies can reference same item. So I thought not to duplicate those values that are not dependent no strategy, but only on the item. Hence I also dragged out the LogTime, as it seems to be the only parameter to unite the logs. But this all looks quite disturbing with those 3 tables. Does it make sense at all? Or you have suggestion?
Pink circles shows my vague attempt of Aggregate Root Paths. I've been thinking in terms of "what entity is responsible for delete". Though I'm unsure about the actual root. I think it's Category. Does it make sense related to User Requests described above?
EDIT1:
(Updated schema, showing typical number of hierarchy items for the first few relations, for 365 days, and additional explanations)
1:1 relation: Sorry. I made a mistake. The StrategyDailyLog should be 1:m. See updated schema. It is one per Strategy, per day.
DayLog / StrategyDailyLog: I’ve been pondering over wether DayLog shall be a part of the hierarchy like this or not. The purpose of the DayLog table is to hold “sum values” derived from all the StrategyDailyLog tables for the same day. Like performance values for this day. It also holds the date value. Which allows me to omit a date value in the StrategyDailyLog (Which I feel would kind of be a duplicate modeling of the date-field), but instead the reference to DayLog exist to “find” the date. I’m not sure if this is an abuse/misconception of normalization.
Null value: I haden’t thought about this. I believe I found 2, as now marked in StrategyDailyLog and ItemAction. They can not be null on creation, but they can be set to null if one need to delete either a Strategy, or a StrategyItem. That should not require a delete of the StrategyDailyLog and the ItemAction. Hence they can be set to null.
All Id –columns: My idea was to have ID (autogenerated Integer) as PK for all my tables. I believed that also would be sufficient as candidate key. Is this not a proper way to make PKs? It’s the only way any table of mine can be identified. I asked a question before if that was ok, maybe I misunderstood, but thought that was a good approach.
m:m relation: This is what I have attempted to do: StrategyItem is the m:m table of StrategyDailyLog / DailyItem.
Ok. Here is me being brutal. I do not understand the model.
So instead of trying to comment on that so much, here are some thoughts that came to my mind when I looked at it.
I think you should have look at your 1:1 relationships (all of them). Why is DayLog and StrategyDailyLog separated in two tables? Probably because you will always have at least one DayLog item but not all DayLog items have a StrategyDailyLog item. If that is the case you can have a StrategyID FK in DayLog table with allow nulls option.
It would help to understand the model if you could show which fields are required and which fields accept null as a value.
All your tables have its own id column. That can be quite confusing when doing 1:1 relations and m:m relations. For a 1:1 relation, usually the relation between the two tables is made on the primary key in both tables. If you do not do that you have to create a candidate key on the foreign key column. In your case that means that StrategyDailyLog should have a candidate key on DayLogID.
A m:m relation between two tables is usually solved by adding a new table in between, with the primary keys from both tables. Those fields together is the primary key for the table in the middle.
Lets say for example that you should have a m:m relationship between Category and Strategy. You should then create a table called CategoryStrategy with two fields CategoryID and StrategyID that together is the primary key for table CategoryStrategy.
I hope my comments makes sense and that they are useful to you.
EDIT 2011-01-17
I do not think that you should have as a principle to use a IDENTITY column as primary key in all tables. A m:m relation does not need it so you should not do it. I also think that you have misunderstood what I meant with a candidate key. A candidate key is a key that could have been used as the primary key. In MS SQL Server you define a UNIQUE CONSTRAINT for your candidate key.
Ex: Table StrategyItem have id as PK but the combination of StrategyID and DailyItemID is the candidate key. Better would be to remove id and use StrategyID+DailyItemID as PK.
Below is the schema that I would have built with your description. I might have missed something important because I do not know everything about what you want to do.
You should not think so much about query performance and building aggregates when designing the schema. That can be handled by creating indexes on columns and using sum, count and group by in your queries. An index on column Created in the model below would be necessary for your queries on a date or date interval. In MS SQL Server there is something called the clustered index. Default the PK of a table is the clustered index but in this case I would make the index on Created column the clustered index.
A Category has 0,1 or more Strategy.
LogItem have on Category and optionally one Strategy
LogItem.Created holds date and time.