Change tables relations to lowest level - sql

I have 4 tables: Project, Design, Customer, Contacts
One project can have multiple designs, each design have customers and that customers have contacts.
In order to retrieve contacts of Projects my team have a table with
ProjectKey CustomerKey ContactKey
They are primary keys of 3 tables (Project, Customer and Contacts)
So actually this table have a lot of data. Problem is we don't want to relate customers and contacts with Project, we want to relate with Design.
What is the best way to change this relation without affecting actual data? I mean now we want that each Design can have their own contacts and customers, so I.E one project can have two customers called "Customer 1" in different designs but they can have different contacts.

You have two options,
First one is to include the DesignKey to your fact table like
ProjectKey, DesignKey, CustomerKey, ContactKey
Second One is to have two fact tables
ProjectKey, DesignKey
DesignKey, CustomerKey, ContactKey
Option one seems better imo. The important factor is you missed the intermediate level design in your original fact table. It must be included since the contact of a same customer changes upon different designs.

Related

How to store editable copies of original data in a relational database?

Let's assume I have two entities: Company and Order.
Company:
Id
Name
Phone
Order:
Id
CompanyId
Name
TotalAmount
I simplified these entities, in the real project they are much more bigger.
In my application, I have a Companies view, where I can do basic CRUD operations. The same is for Orders.
When I create an order I must choose the company from my database. The problem is that I must allow the user to modify company data for each order, so it can be modified only for particular order.
I have 2 solutions:
First solution:
Create a separate table OrderCompany where I can store copies of Companies data for each order. In this case, I can edit the copy and it will not affect the original company, but I have doubts because it will be a full copy of the Contacts table with only one additional field - OrderId.
Second solution:
Store copies of companies directly inside the Companies table and add OrderId in this table. Original companies will be stored with OrderId = null, for copies OrderId will be assigned. In this case, I don't have 2 almost identical tables like in the first solution, but I'm not sure that storing originals and copies in the same table is a good idea.
Which of these two solutions is better in your opinion? Maybe there is a better way?
I suspect that you are confusing some different concepts. A "company" should not be changing. However, companies might have something -- say "contacts" -- that do change.
So, I think you want a model where you have:
companies, which has basic information about companies, such as companyid and company name and so on. This information does not change (or at least not per order). A company would also have a default "contact".
companyContacts, which would be for a contact in a company. This would have a companyId and then additional information. Different contacts might be used for different orders.
orders which would have a companyContactId.
Then the order would be assigned to a company and to a particular contact within the company. New contact information can be created as necessary,.
I suppose we can go with your 1st approach as any change in the company table will not cost any changes in OrderCompany table.

Database Design for Contacts

So I have 3 main entities. Airports, Customers, and Vendor.
Each of these will have multiple contacts I need to relate to each.
So they way I set it up currently.
I have the following tables..
Airport
Customer
Vendor
I then have one Contacts table and a xref for Airport, Customer, Vendor...
I am questioning that and was thinking a contacts table for each ..
Airport and AirportContacts
Customer and CustomerContacts
Vendor and VendorContacts
Any drawbacks to either of these designs?
To me, the deciding factor is duplication of entities vs "one version of the truth". If a single real-world person can be a contact for more than one of the other entities, then you don't want to store that single person in multiple contact tables, because then you have to maintain any changes to his/her properties in multiple places.
If you put the same "Joe Smith" in both AirportContacts and VendorContacts, then one day when you look and see his city is "Denver" in one table and "Boston" in another table, which one will you consider to be the truth?
But as someone mentioned in comments, if a contact can only be associated with one of the three other entities ("types" as you call them), then putting them in separate tables makes the most sense.
And there's yet a third scenario. Say "Joe Smith" can be a contact for both Airports and Vendors. But say that he has some properties, like his gender and age, which are the same regardless of which "type" he is being considered, but there might be some properties, like phone number, or position/job title, which could depend on the "type". Maybe he uses one phone in his capacity as an Airport Vendor, and a different phone as a Vendor Contact. Moreover, maybe there are some properties that apply to one type of contact that don't apply to the others. In these cases, I would look at some kind of hybrid approach where you keep common properties in a single Contact table, and "Type"-specific properties in their own type-related tables. These type-related tables would be bridge tables that have FKs back to the Contact table and to the main entity table of the "Type" they are related to (Vendor, Customer or Airport).
What I have so far ... Dont mind some of the data types.. just placed quick placeholders..

store product and category in one table is good or else we can use seperate table for category and product?

I am totally confused to store category and product data stored in the same table in hierarchical relation/Parent-child relation use in a table or if we create two separate table for category and product table?
in above table, i used the same table for storing category and product with parentId and childId, If we use like this then what benefits? Or we use a separate table for category and product and why? Please anyone help me
This really depends on if the relationship between store and product categories are one to many or many to many and if a single category can only belong to one category tree.
If the relationship is one to many, and a category can only belong to one tree, then you'll be able to use a single table, with a foreign key referencing the same table.
Otherwise, you'll likely be looking 2 or 3 tables. At a minimum you'll need one table for your categories, and then another for you relationship (what's known as a composite key table).
Also, if Product categories and Store Categories are inherently different (hold different data) then you should be using separate tables for them anyway.

Database Design - sales from multiple sources

We currently have a SQL database with a table that holds online sales for our company, which sells products using other websites (say, Amazon). The table schema has been set up to hold specific sale data/attributes provided by the website our items are currently sold on (say, Site A).
We are expanding sales to other websites that provide different attributes than Site A uses when an item is sold (e.g. Site A might provide a unique sales id number, and site B might not provide a unique sales id number, but also provide some other info that Site A doesn't provide that we still need to capture).
The question is do I add a separate table for sales on each 'site' that we sell on, as the schema will be different, or try to combine all sales into one table, no matter the platform, leaving some columns null if it doesn't pertain to the particular platform? Or maybe a hybrid approach, separating only the attributes that aren't common among the two sites into separate tables, while a "master" sales table holds attributes that are shared (sale_price, sale_date, etc)?
There are also other tables in play that hold internal information (product Ids, costs, etc), that are linked to the sales table via a unique identifier. Whichever route I choose, I'd need come up with a unique identifier I could use across all tables (auto incremented sale_id, e.g.), and store that in a table for reference/joins.
Any suggestions are welcomed!
A sale is a sale >> same data belongs to the same table. I would definitely not recommend splitting your sales to several tables as this creates lots of difficulty for all that might follow: sales statistics and so on. Try to keep all sales in one table.
If it's a very small project, it might be the best shot to integrate the different fields into one table. Otherwise you might try to create profiles for every sale platform: In this case, use an Entity-Attribute-Value model.
Do not add a table for each site. It sounds like you have a many to many relationship between sites and attributes, so set up your database that way. Also, for any unique identifier you need, create it yourself.

Doubt regarding a database design

I have a doubt regarding a database design, suppose a finance/stock software
in the software, the user will be able to create orders,
those orders may contain company products or third-party products
typical product table:
PRIMARY KEY INT productId
KEY INT productcatId
KEY INT supplierId
VARCHAR(20) name
TEXT description
...
but i also need some more details in the company products like:
INT instock
DATETIME laststockupdate
...
The question is, how should i store the data?
I'm thinking in 2 options:
1 -
Have both company and third-party, products in a single table,
some columns will not be used by third-party products
identify the company products are identified by a supplier id
2 -
Have the company products and third-party in separated tables
3 - [new, thanks RibaldEddie]
Have a single product table,
company products have additional info in a separated table
Thanks in advance!
You didn't mention anything about needing to store separate bits of Vendor information, just that a type of product has extra information. So, you could have one products table and an InHouseProductDetails table that has a productId foreign key back to the products table that stores the company specific information. Then when you run your queries you can join the products table to the details table.
The benefit is that you don't have to have NULLable columns in the products table, so your data is safer from corruption and you don't have to store the products themselves in two separate tables.
Oooo go with 3! 3 is the best!
To be honest, I think the choice of #1 or #2 are completely dependent upon some other factors (I can only thing of 2 at the moment):
How much data is expected (affecting speed of queries)
Is scalability going to be a concern anywhere in the near future (I'd guess within 5 years)
If you did go with a single table for all inventory, then later decided to split them, you can. You suggested a supplier identifier of some sort. List suppliers in a table (your company included) with keys to your inventory. Then it really won't matter.
As far as UNION goes, it's been a while since I've written raw Sql - so I'm not sure if UNION is the correct syntax. However, I do know that you can pull data from multiple tables. Actually just found this: Retrieving Data from Multiple Tables with Sql Joins
I agree with RibaldEddie. Just one thing to add: put a unique constraint on that foreign key in your InHouseProductDetails table. That'll enforce that it's a one-to-one relationship between the two tables, so you don't accidently end up with two InHouseProductDetails records for one product (maybe from some dataload gone awry or something)
Constraints are like defensive driving; they help prevent the unexpected...
I would advice on using point #1. What happens when another supplier comes along? It's also more easy to extend on one product table/produst class.
Take into account the testing of your application also. Having all data in one table raises the possible requirement of testing both the 3rd Party & Company elements of your app for any change to either.
If you're happy that your Unit test would cover this off its not so much of a worry... if you're relying on a human tester then it becomes more of an issue when sizing the impact of changes.
Personally I'd go for the one products table with common details and separate tables for the 3rd party & Company specifics.
one table for products with a foreign key to the Vendor table; include your own company in the Vendor table
the Stock table can then be used to store information about stock levels for any product, not just yours
Note that you need the Stock table anyway, this just make the DB model more company-agnostic - so if you ever need to store stock level information about third-party products, there's no DB change required