Partitioned view on large parent and child table with foreign key - sql

How can I do partitioned view on SQL Server (Standard edition) on two tables with foreign key - parent and child 1TB each - without changing queries called from application, so that queries are not inefficient?
Here is the schema (simplified): ( or on SQL Fiddle)
CREATE TABLE Product
(`idProduct` int,
`DateProduced` datetime,
`productName` varchar(7),
`description` varchar(55),
PRIMARY KEY (`idProduct`)
);
CREATE TABLE ProductPhoto
(`idProduct` int primary key,
`Image` BLOB);
CREATE TABLE ProductExport
( `idExport` int primary key,
`idProduct` int,
`TimeExported` datetime,
`quantity` int);
alter table ProductPhoto
add constraint fk1_Photo foreign key (`idProduct`) references Product(`idProduct`);
alter table ProductExport
add constraint fk1_Export foreign key (`idProduct`) references Product(`idProduct`);
Here are possibilities:
a) if I make partitioned view on table Product based on DateProduced (partitions would be by month each), I cannot search by table's primary key effectively (SELECT * FROM Product WHERE idProduct=3 will search in all partitions of table Product).
b) if I make partitioned view on table Product based on idProduct, I cannot search by DateProduced effectively.
I have also problem how to make both tables partitioned.
Is it possible to somehow make a reasonable partitioned view with both tables, with no large changes for queries (search all product between dates, get product by productId), so that it wouldnt be too slow?

Related

Sql creating table consisting of keys from other tables

this is probably a simple question but I am quite new to SQL and databases, so I have been following this site: https://www.postgresqltutorial.com/postgresql-foreign-key/ to try and create a table that consist of primary keys from other tables.
Here I have the structure of the database in an excel overview. With colors showing the relations. i am having problems with the One-To-Many tables. As I get the same error every time "ERROR: column "id" referenced in foreign key constraint does not exist
SQL state: 42703".
The SQL query:
DROP TABLE IF EXISTS ingredient_to_unit_relations;
DROP TABLE IF EXISTS ingrediens;
CREATE TABLE ingrediens (
id serial,
name_of_ingredient varchar(255),
price_per_unit int,
PRIMARY KEY (id)
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id
FOREIGN KEY (id)
REFERENCES ingrediens (id)
);
You need to define the column in order to declare it as a foreign key:
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
ingredient_id int,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingrediens (id)
);
I might recommend some somewhat different naming conventions (I changed the name id in the table above):
CREATE TABLE ingredients (
ingredient_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name varchar(255),
price_per_unit int
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
ingredient_id int,
CONSTRAINT Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingredients (ingredient_id)
);
Notes:
I am a fan of naming primary keys after the table they are in. That way, foreign keys and primary keys usually have the same name (and you can use using if you choose).
Avoid SERIAL. GENERATED ALWAYS AS IDENTITY is now recommended.
You can inline primary key constraints (as well as other constraints).
There is not generally a need to repeat the table name in a column (other than the primary key). So, name instead of name_of_ingredient.
Using int for a monetary column is suspicious. It doesn't allow smaller units. That might work for some currencies but in general I would expect a numeric/decimal type.

How to connect two fact tables to one dimensional table

I have two fact tables (HistoricTable, ForecastTable). Both tables use a composite key that combines the productID and WeekID together. The ForecastTable has future weekID's & historic has previous ones. I want both of these ProductID's to reference one Dimensional table called ProductTable. How do I connect them?
My assumption would be to create an additional table that queries HistoricTable & ForecastTable via UNION join and have that connected to the ProductTable. Is this logic correct?
Table Image Layout
I want both of these ProductID's to reference one Dimensional table called ProductTable.
You can establish one foreign key between historic and product and another foreign key between forecast and product.
For example:
create table product (
id int primary key not null,
name varchar(10)
);
create table historic (
product_id int not null references product (id),
week_id int not null,
units_sold int,
primary key (product_id, week_id)
);
create table forecast (
product_id int not null references product (id),
week_id int not null,
forecast_units int,
primary key (product_id, week_id)
);

Storing foreign key linked in a separate table? SQL

So I went through Odoo database design and I saw that they stored the relationship between 2 tables in a separate table that doesn't have primary key. How are you able to do this? I want to replicate this kind of behavior in SQL Server. Is it auto-inserted?
A table should always have a primary key. Look at the thousands of questions on Stackoverflow that ask how to delete one of two identical rows in a database table.
You typically model m-to-n relationships between tables with a separate table that has foreign keys to both tables:
CREATE TABLE person (
person_id bigint PRIMARY KEY,
name text,
...
);
CREATE TABLE game (
game_id bigint PRIMARY KEY,
name text NOT NULL,
...
);
CREATE TABLE likes_to_play (
person_id bigint REFERENCES person NOT NULL,
game_id bigint REFERENCES game NOT NULL,
PRIMARY KEY (person_id, game_id)
);
CREATE INDEX ON likes_to_play (game_id);
The primary key on the table makes sure there are no superfluous double entries and backs one of the foreign keys. The other index is created for the other foreign key.

Is it possible to reference a foreign key to parent table?

CREATE TABLE Product
(
"Product_id" int,
"Stock_quantity" int,
"Product_name" varchar(50),
"Model" varchar(50),
"Average_rating" float(3),
"RAM" int,
"Color" varchar(20),
"Price" float(10),
PRIMARY KEY ("Product_id")
);
CREATE TABLE Sale
(
"Sale_id" int,
"Sale_date" date,
"Employee_id" int,
"Customer_id" int,
"Product_id" int,
"Product_quantity" int,
"Rating" int,
PRIMARY KEY ("Sale_id"),
FOREIGN KEY("Employee_id") REFERENCES Employee("Employee_id") ,
FOREIGN KEY("Customer_id") REFERENCES Customer("Customer_id") ,
FOREIGN KEY("Product_id") REFERENCES Product("Product_id")
);
CREATE TABLE Computer
(
"Type" varchar(10),
"Processor" varchar(20),
"Monitor_size" int
) inherits(Product);
CREATE TABLE Mobile
(
"Os" varchar(30),
"Screen_size" int
) inherits(Product);
Here is my tables while insertion of sale rows I get this error.
ERROR: insert or update on table "sale" violates foreign key constraint "PK_Product_id"
SQL state: 23503
Detail: Key (Product_id)=(12) is not present in table "product".
It says there is no presence of the row, but I can see them when I view the table:
I inserted every product as computer or mobile not as product.
You are stumbling over one of the many quirks with inheritance: There are no “global” constraints on an inheritance hierarchy, consequently you cannot have a foreign key to a inheritance hierarchy.
The primary key you defined on product does not extend to computer.
Even though a SELECT on product will append the results for the inheritance children as well, these are not part of the table parent and consequently cannot be used as target for the foreign key. The foreign key is between sale and product only, the inheritance children are excluded.
There is no proper way to do this with inheritance.
It is better for computer not to be an inheritance child of product, but to have a foreign key to product (with a unique constraint on it), so that the data for a computer object will be split between the two tables. This is somewhat inconvenient for queries, but you can have a foreign key that way.
Here is an example:
CREATE TABLE product (
product_id integer PRIMARY KEY,
prodname text NOT NULL
);
CREATE TABLE computer (
product_id integer PRIMARY KEY,
processor text NOT NULL,
FOREIGN KEY (product_id) REFERENCES product(product_id)
);
CREATE TABLE sale (
sale_id integer PRIMARY KEY,
product_id integer NOT NULL REFERENCES product(product_id)
);
Now there is no direct foreign key reference from sale to computer, but since the product_id of computer and product is identical, you can always find the unique computer for a sale if it exists:
SELECT p.prodname, c.processor
FROM sale s
JOIN product p USING (product_id)
LEFT JOIN computer c USING (product_id)
WHERE sale_id = 42;
If you have more product “subtypes”, you can add more left joins.

How to reference two foreign key attributes within one column?

I'm working on building a database in Oracle SQL developer. In context to the scenario I have a primary table which holds two rovers.
Here is the code for that table:
CREATE TABLE "ROVER" (
Rover_Model_ID varchar(7) NOT NULL,
Rover_Name varchar(50),
Manufacturer varchar(50),
CONSTRAINT Rover_PK PRIMARY KEY (Rover_Model_ID)
);
The way I currently have it, is that there are two rovers in this table. (Refer to the image at the end of the post)
There is also another table called Thermal_System_Components. Which has 3 component entries that both of the rovers use.
CREATE TABLE "THERMAL_SYSTEM_COMPONENT" (
Component_ID INT,
Component_Type varchar(20),
Rover_Model_ID INT NOT NULL,
CONSTRAINT TSC_PK PRIMARY KEY (Component_ID),
CONSTRAINT TSC_FK FOREIGN KEY (Rover_Model_ID) REFERENCES
ROVER(Rover_Model_ID)
);
My question relates to this scenario. There are 3 components which both rovers use, so I wondered how do I go about successfully inputting data into these tables to highlight that BOTH rovers use each of the 3 components. I've inserted the table of my initial concept down below.
If anyone could help clarify this for me I'd be most appreciative.
This is called a many-to-many relationship.
What you need is a third table, mapping rovers to components. Each pair of rover/component takes one row in this table, so there will be six rows total.
CREATE TABLE "ROVER_HAS_COMPONENT" (
Component_ID INT NOT NULL,
Rover_Model_ID INT NOT NULL,
CONSTRAINT TSC_PK PRIMARY KEY (Component_ID, Rover_Model_ID),
CONSTRAINT TSC_FK FOREIGN KEY (Component_ID) REFERENCES
THERMAL_UNIT_COMPONENT(Component_ID),
CONSTRAINT TSC_FK FOREIGN KEY (Rover_Model_ID) REFERENCES
ROVER(Rover_Model_ID)
);
You don't need the Rover_Model_ID in your component table.
PS: You also need the data type in each foreign key column to match the data type of the primary key they reference.