Create db schema - database

Consider a scenario where electronics is a main category and TV, fridge etc. are the sub categories, how you will a create db schema (table structure) for it using single table?

I would add a nullable column that reference the identity column of itself.
Eg:
CategoryID (primary key) NOT NULL
CategoryName NOT NULL
ParentCategoryID NULL reference CategoryID
Querying those type of hierarchical table is sometimes tricky, however you can create an unlimited levels of subcategories.

Use ENUM
CREATE TABLE electronics (
...
category ENUM("TV", "fridge", "etc"),
...
);
and if you need a multiple depth for categories:
CREATE TABLE electronics (
...
category ENUM("TV", "fridge", "etc"),
parent_category ENUM("TV", "fridge", "etc"),
...
);

Related

what is the correct way to design a 'table to row' relationship?

I am trying to model the following in a postgres db.
I have N number of 'datasets'. These datasets are things like survey results, national statistics, aggregated data etc. They each have a name a source insitution a method etc. This is the meta data of a dataset and I have tables created for this and tables for codifying the research methods etc. The 'root' meta-data table is called 'Datasets'. Each row represents one dataset.
I then need to store and access the actual data associated with this dataset. So I need to create a table that contains that data. How do I represent the relationship between this table and its corresponding row in the 'Datasets' table?
an example
'hea' is a set of survey responses. it is unaggregated so each row is one survey response. I create a table called 'HeaData' that contains this data.
'cso' is a set of aggregated employment data. each row is a economic sector. I create a table called 'CsoData' that contains this data
I create a row for each of these in the 'datasets' table with the relevant meta data for each and they have ids of 1 & 2 respectively.
what is the best way to relate 1 to the HeaData table and 2 to the CsoData table?
I will eventually be accessing this data with scala slick so if the database design could just 'plug and play' with slick that would be ideal
Add a column to the Datasets table which designates which type of dataset it represents. Then a 1 may mean HEA and 2 may mean CSO. A check constraint would limit the field to one of the two values. If new types of datasets are added later, the only change needed is to change the constraint. If it is defined as a foreign key to a "type of dataset" table, you just need to add the new type of dataset there.
Form a unique index on the PK and the new field.
Add the same field to each of the subtables. But the check constraint limits the value in the HEA table to only that value and the CSO table to only that value. Then form the ID field of Datasets table and the new field as the FK to Datasets table.
This limits the ID value to only one of the subtables and it must be the one defined in the Datasets table. That is, if you define a HEA dataset entry with an ID value of 1000 and the HEA type value, the only subtable that can contain an ID value of 1000 is the HEA table.
create table Datasets(
ID int identity/auto_generate,
DSType char( 3 ) check( DSType in( 'HEA', 'CSO' ),
[everything else],
constraint PK_Datasets primary key( ID ),
constraint UQ_Dateset_Type unique( ID, DSType ) -- needed for references
);
create table HEA(
ID int not null,
DSType char( 3 ) check( DSType = 'HEA' ) -- making this a constant value
[other HEA data],
constraint PK_HEA primary key( ID ),
constraint FK_HEA_Dataset_PK foreign key( ID )
references Dataset( ID ),
constraint FK_HEA_Dataset_Type foreign key( ID, DSType )
references Dataset( ID, DSType )
);
The same idea with the CSO subtable.
I would recommend an HEA and CSO view that would show the complete dataset rows, metadata and type-specific data, joined together. With triggers on those views, they can be the DML points for the application code. Then the apps don't have to keep track of how that data is laid out in the database, making it a lot easier to make improvements should the opportunity present itself.

multiple prices 1 item

I'm wondering if this would be the best way to build a table for an item that can have more than 1 price. Each product is identified by its model_number. Should I use a prefix before the model_number for each individual seller? I can't use model_number for the primary key. For example:
seller_product_id model_number seller price
SELLER_1_MODEL_NUMBER MODEL_NUMBER seller_1 9.99
SELLER_2_MODEL_NUMBER MODEL_NUMBER seller_2 19.99
For the sake of loose coupling, I suggest you build seperate Items and Price tables, and have another table (called Junction table) Item_Price which maps many items to many prices as you like.
This is called Many-to-Many relationship
Basically, it links an Item with its itemId to a Price with priceId, and stores this link in an Item_Price itemPriceId (or whatever you call the 3rd primary key)
Here's a sample diagram EDIT: sorry about the previous diagram.
Here's a sample SQL DDL of 3 tables, plus 2 junction tables to associate Item to Price, and Seller to Item.
CREATE TABLE Item (
item_id int PRIMARY KEY,
..
..
)
CREATE TABLE Price (
price_id int PRIMARY KEY,
..
..
)
CREATE TABLE Seller (
seller_id int PRIMARY KEY,
..
..
)
-- This is the junction table for Item to Price mapping.
CREATE TABLE Item_Price (
item_id int REFERENCES Item (item_id),
price_id int REFERENCES Price (price_id),
PRIMARY KEY (item_id, price_id)
)
-- This is the junction table for Seller to Item mapping.
CREATE TABLE Seller_Item (
seller_id int REFERENCES Seller (seller_id),
item_id int REFERENCES Item (item_id),
PRIMARY KEY (seller_id, item_id)
)
One attribute that have many properties? Sounds like one-to-many relations... go for a new table have foreign key help you out.
Products
prod_id (PK) | model_no
Sellers
seller_id(PK)|seller_name
Pricing
price_id (PK)|price|prod_id (FK) | seller_id(FK)
yes You can a prefix before the model_number for each individual seller.
If you still have stuff then let me know more clear your problem

Composite foreign key in SQL Server

I have a table named Books which contains 3 columns.
TableName: Books
Columns: BookId (PK), BookName, Book_Publisher_XRef_Id (FK), IsInternal
I have two tables that contains publisher information. Both these tables have different set of columns.
TableName: InternalPublishers
Columns: PublisherId (PK), PublisherName, ....
TableName: ExternalPublishers
Columns: PublisherId (PK), PublisherName, ....
I have a link table that contains information about which book belongs to which publisher. One book can have multple publishers.
TableName: Books_Publishers_XRef
Columns: Book_Publisher_XRef_Id (PK), PublisherId
If I want to create a Foreign Key constraint on PublisherId, I need to create sort of Composite Foreign Key constraint which I am not sure can be created.
So in this scenario, what is the best way to achieve FK on PublisherId in Books_Publishers_XRef table?
Break Books_Publishers_XRef table in 2 tables i.e. one for Internal Publishers and another one for External Publishers and have 2 columns in Books table for Books_Internal_Publishers_XRef and Books_External_Publishesr_XRef tables?
Don't create FK on Publisher_Id column and leave the design as it is?
Create composite FK by adding Publisher_Type_Id column in Books table and Books_Publishers_XRef table where if Publisher_Type_Id = 1, it belongs to Internal_Publishers table and Publisher_Type_Id = 2, it belongs to External_Publishers table ? (Not sure if this is possible)
Some other schema design?
Please advise.
Don't divide your data amongst two tables: InternalPublishers, ExternalPublishers. Create one table and have a bit field to determiner whether they are internal or external. Something like this:
create table Publisher
(
PublisherId int not null primary key clustered,
PublisherName varchar(100) not null,
IsInternal bit not null
)
go
That way you can easily create your foreign key reference. After all, you seem to have this same design for Books, keep that going to publishers.
Keep all common columns in the Publisher table.
Subtype tables have only columns specific to each one.

How to design a Tag table from another tables?

I'm designing a software that will use tags to identify posts similar to StackOverflow, but with some differences.
The tags must be loaded dinamically (like here), but come from various different tables because it will be used for identification.
Example: the tag Brazil identifies an country in the country table, the tag Monday identifies a day in the week day table.
I need an idea of how design this in the database. How have the tags from all tables loading, but identifying the correct table the data belongs.
This might do what you want:
CREATE TABLE countries (
name VARCHAR PRIMARY KEY,
...
);
CREATE TABLE weekdays (
name VARCHAR PRIMARY KEY,
...
);
CREATE VIEW tags AS
(SELECT name AS tag, 'countries' AS source
FROM countries)
UNION ALL
(SELECT name AS weekdays, 'weekdays' AS source
FROM weekdays)
UNION ALL ...;
Then you can make additional tables and add them to the view. When you tag some other table, you'll treate the name and source of the tag as the primary key and refer to this view, like so:
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
...
);
CREATE TABLE foo_tags (
foo_id INTEGER REFERENCES foo,
tag_name VARCHAR,
tag_source VARCHAR
);
Unfortunately, it isn't possible to define a foreign key from the table foo_tags to the view tags defined above.

store equal records in multiple tables

im developing a simple access application that helps us to order the right products for a project. i have a table for each contractor containing its products. i have a table "favorite-products" that relates to products and gives additional information how and when they should be used.
normally id have a big table (containing all products) that has a contractor-column. i my favorite-products table i could then easyly relate to a product. but here i need to keep the products in separate tables. so whats the best way to connect my favorite-products table with the products in the contractor-tables?
thanks :)
This is not the best design.
You should UNION all contractor tables together and JOIN with the result:
SELECT *
FROM (
SELECT product
FROM contractor1
UNION ALL
SELECT product
FROM contractor2
UNION ALL
…
) c
JOIN favorite f
ON f.product = c.product
You better keep one single table for you products with contractor as a field.
It will be much easier to query and to manage.
I would create a contractors table, a product table and then a many-to-many linked table contractors to products. Also i would create a favorite-products table in which you can also have a many-to-many contractors to products link for those cases where a product can come from more than 1 contractor
So, you'll have a Contractor, Product and Contractor_Product table. Something like (in psuedo-sql):
create table Contractor {
id int primary key,
name varchar(50) not null,
...
}
create table Product {
id int primary key,
name varchar(50) not null,
...
}
create table Contractor_Product {
contractorid int references Contractor(id),
productid int references Product(id),
...,
primary key contractorid, productid
}
Now, I'm not 100% sure what you want from the "Favorites" table. It may not be a table, but rather a query. Or, maybe you want a table that similar to the Contractor_Product table? Or just another "isfavorite bool default=false" column on the Contractor_Product table?
Hope that helps!

Resources