I'm learning partitioning tables in SQL Server and I got stuck with this problem: I have 2 linked tables - parent and child. One of them (or maybe even both) is a partitioned table. When I'm implementing a partitioned view do I need to include 2 identical columns in it - the one that references parental table (from child) and the primary key that is being referenced (from parent)?
I'm having troble with it since MSDN says:
Column Rules:
All columns in each member table must be included in the select list. SELECT * FROM is acceptable syntax.
But views should make the representation of (linked) tables easier, so not all the columns should be included in view.
And in my case, according to MSDN I have to include all the columns of both tables into a view (and 2 of them would be identical). It seems to me as not very logical solution.
For example:
Database 1:
create table manufacturer
(
id int,
manufacturer_name varchar(35),
PRIMARY KEY (id),
CONSTRAINT CHK_manufacturer_id
CHECK (id < 1000)
);
create table product
(
pid int,
product_name varchar(35),
mid int,
PRIMARY KEY (pid),
CONSTRAINT CHK_product_pid
CHECK (pid < 1000),
CONSTRAINT FK_product_mid
FOREIGN KEY (mid)
REFERENCES manufacturer(id)
);
Database 2:
Same tables with CHECK constraints (id >= 1000)
View:
create view dist_view as
select *
from db1.product p1
inner join db1.manufacturer m1 on p1.mid = m1.id
UNION ALL
select *
from db2.product p2
inner join db2.manufacturer m2 on p2.mid = m2.id
So the view with look like
pid | prod_name | mid | id | manufact_name
and mid = id.
In my opinion a view like this contradicts the main advantage of using views - simple representation of tables. So I would like to have a view like this:
(pid) | prod_name | manufact_name
How do I solve this?
First, you probably should not bother learning about partitioned views. The correct way to do partitioning is using partitioned tables, rather than views.
This is repeated in the documentation. For instance:
Note
The preferred method for partitioning data local to one server is
through partitioned tables. For more information, see Partitioned
Tables and Indexes.
(And I note that your queries are all on one server.)
Second, a partitioned view is created by union all on base tables. You are using joins, so that is just a regular view.
I would suggest that you re-evaluate your data structures and think more about partitioned tables than partitioned views.
Related
I need to create a table having a field, which is a foreign key referencing to another query rather than existing table. E.g. the following statement is correct:
CREATE TABLE T1 (ID1 varchar(255) references Types)
but this one throws a syntax error:
CREATE TABLE T2 (ID2 varchar(255) references SELECT ID FROM BaseTypes UNION SELECT ID FROM Types)
I cannot figure out how I can achieve my goal. In the case itβs needed to introduce a temporary table, how can I force this table being updated each time when tables BaseTypes and Types are changed?
I am using Firebird DB and IBExpert management tool.
A foreign key constraint (references) can only reference a table (or more specifically columns in the primary or unique key of a table). You can't use it to reference a select.
If you want to do that, you need to use a CHECK constraint, but that constraint would only be checked on insert and updates: it wouldn't prevent other changes (eg to the tables in your select) from making the constraint invalid while the data is at rest. This means that at insert time the value could meet the constraint, but the constraint could - unnoticed! - become invalid. You would only notice this when updating the row.
An example of the CHECK-constraint could be:
CREATE TABLE T2 (
ID2 varchar(255) check (exists(
SELECT ID FROM BaseTypes WHERE BaseTypes.ID = ID2
UNION
SELECT ID FROM Types WHERE Types.ID = ID2))
)
For a working example, see this fiddle.
Alternatively, if your goal is to 'unite' two tables, define a 'super'-table that contains the primary keys of both tables, and reference that table from the foreign key constraint. You could populate and update (eg insert and delete) this table using triggers. Or you could use a single table, and replace the existing views with an updatable view (if this is possible depends on the exact data, eg IDs shouldn't overlap).
This is more complex, but would give you the benefit that the foreign key is also enforced 'at rest'.
I'm currently working on a simple dummy project to refresh my knowledge on SQL and to learn a few new things :)
I have a table Article with the columns:
aID, price
I have another table Storage:
sID, aID, count
The Storage table references the aID as a foreign key and the count column say how much of an article is stored.
Now I want to add a column value to my Storage table. This column should be calculated by Article.price * Storage.count.
I found after searching the web that you can have calculated columns like this
CREATE TABLE tbl
(
int1 INT,
int2 INT,
product BIGINT GENERATED ALWAYS AS (int1 * int2) STORED
);
But I haven't found an example how to this with columns from another table.
What do I have to do in order to use the price from the referenced aID in the calculation?
You cannot define a generated column based on values from other tables. Per the documentation:
The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.
You can achieve the expected behavior by creating two triggers on both tables but usually creating a view based on the tables is a simpler and more efficient solution.
I'm trying to create a table in Postgres to represent a many-to-many relationship between rows of the same table.
I have a table called outerwear (which is like jackets, etc) and I want to create a many-to-many relationship between instances of outerwear.
I'm wondering what the best way is to create a join table to model this relationship that takes into account the fact that A to B is the same as B to A. So far I have this (which is just a normal join table):
CREATE TABLE outerwear_outerwear_join (
a_outerwear_id integer REFERENCES outerwear,
b_outerwear_id integer REFERENCES outerwear,
PRIMARY KEY(a_outerwear_id, b_outerwear_id)
);
But again this does not account for the fact that flipping the order of the columns should not change the value/uniqueness of a row.
Create a UNIQUE INDEX , using least and greatest functions.
CREATE UNIQUE INDEX unq_test_a_b
ON outerwear_outerwear_join ( LEAST(a_outerwear_id, b_outerwear_id), GREATEST(
a_outerwear_id, b_outerwear_id));
Demo
I am trying to build a table which will hold the 'relationship' of a parent table and a child table. However each column in both tables are no keys or unique and there are duplicate values in each.
Example
Table A - Parent (Fact)
**CartNumber**
Table B - Child
**CartNumber** not unique
CartValue
CartNumber from table A links to CartNumber in B.
I have tried to implement a foreign key with NOCHECK but of course that will not work since the child column is not a primary key or unique. Bear in mind, I am ONLY trying to define that there is a link between the two columns/tables. Is there any way to define a 'loose' relationship between the two columns? Preferably a method where I can reference the sys views or information schema to extract this information
To be honest: This design smells and - if possible - you should think about changing this...
There is no chance to define a FOREIGN KEY CONSTRAINT on non-unique columns the way you describe it.
But: To define a JOIN there is no need for a FK!
My suggestion:
Create a VIEW like this:
CREATE VIEW dbo.MyView
AS
SELECT a.Col1,a.Col2,...
,b.Col1,b.Col2,...
FROM TableA AS a
[INNER/LEFT/RIGHT/FULL OUTER] JOIN TableB AS b ON a.RelField=b.RelField;
With such a VIEW you will get the data joined on this non-unique information.
UPDATE
Taken form your comment:
the end goal is just to provide an external web service with information that says Column A from Table A is used to join onto Column B from Table B
You can create a meta-table like this:
CREATE TABLE dbo.ColumnReference
(
ColumnReferenceID INT IDENTITY
,TABLE_NAME_A VARCHAR(255) NOT NULL
,COLUMN_NAME_A VARCHAR(255) NOT NULL
,TABLE_NAME_B VARCHAR(255) NOT NULL
,COLUMN_NAME_B VARCHAR(255) NOT NULL
);
--inlcude SCHEMA if needed...
In this case you can maintain these relations in your own structure..., you might even add details, rules, what ever...
The web service will call this directly. You might use a VIEW to combine existing relations (defined as FK CONSTRAINT) with your own meta table (simply with UNION ALL).
I am working on SQL Server and want to create a partition on a table. I want to base it off of a foreign key which is in another table.
table1 (
fk uniqueidentifier,
data
)
fk points to table2
table 2 (
partition element here
)
I want to partition table1 base on table2's data, ie if table2 contains categories
The foreign key relationship doesn't really matter, horizontal partitioning is based on the values in the table itself. The foreign key just makes sure they already exist in another table.
Links:
SQL SERVER β 2005 β Database Table Partitioning Tutorial β How to Horizontal Partition Database Table
Partitioning a SQL Server Database Table
Steps for Creating Partitioned Tables