Relation in relational model : heading and body meaning? - sql

A relation in the relational model is what SQL represents with a table. We could say that a table is an attempt by SQL to represent a relation.
Getting back to a relation, which is what SQL attempts to represent with a table: a relation
has a heading and a body. The heading is a set of attributes (what SQL attempts to represent
with columns), each of a given type. An attribute is identified by name and type name. The
body is a set of tuples (what SQL attempts to represent with rows). Each tuple’s heading is the
heading of the relation. Each value of each tuple’s attribute is of its respective type.
What do we mean by the heading of a relation is a set of attributes, and the body is a set of tuples?
If we consider these two tables :
Employee : EmployeeId,FirstName,LastName,DepartmentId
Department : DepartmentId, DepartmentName, Description
If I want to select the employees and their departments, the query will be like following :
SELECT * FROM Employee E
LEFT Department D ON E.DepartmentId=D.DepartmentId
In this case what is the heading and the body corresponding to mathematic definition of relational ?

In the relational model
An attribute is a name paired with a data type.
A set of attributes with unique names is called a heading.
A tuple is a set of attribute values corresponding to a specific heading.
A relation is a unsorted, unique set of tuples.
A tuple can only be a part of a relation if their heading match exactly.
A set of tuples that all correspond to the same heading is called a body.
Therefor, a relation the combination of a specific heading and a body (which is a set of tuples that correspond to this heading).
In a relational database
A relation is implemented as a table.
(Note: The relational model describes the tuples in a relation as unique, but no RDBMS I know of enforces that rule unless a unique key (in the form of a primary key, unique constraint or unique index) is declared.
A Heading is the table's column definition.
A tuple is a row within a table.
An attribute value is the value of a specific column in a specific row.
To answer your question
In this case what is the heading and the body corresponding to mathematic definition of relational ?
Given the tables you've described in your question, and the query you're using to select from these table, the resultset of that query can not be considered as a relation, since it has a duplicate attribute in it's heading - the DepartmentId column exists in both source tables.
This is why the database will not let you create a view (or a cte) from this query - since a view or cte column names must be unique in order to provide a proper heading.
For more information, read Relation (database) over on Wikipedia.

Related

SQL Referencing a particular table chosen from a row value in another table

I've got a database called SimpleCredentials in which there is a table called dbo.Properties which has (PK) UserID and then some other attributes like Name, Date of Birth etc. There is another Primary Key attribute called ExtendedCredentials which is a string dbo.UserID. So, for example the user with UserID = S-1-5-21-2177 will have the string dbo.S15212177 in their ExtendedCredentials column.
I've got another database called ExtendedCredentials. For every User there is a unique table in that database. Using the previous example, there will be a table called dbo.S15212177.
So, if I have 100 users there will be 100 rows in the dbo.Properties table in the SimpleCredentials database, and there will be 100 unique tables incorporating their UserID in the ExtendedCredentials database.
I want to create an entity relationship diagram, and eventually a MS SQL schema, but how do I represent the multiplicity of dbo.UserIDs and their relationship to their dbo.UserID string attribute in dbo.Properties?
Am I getting something fundamentally wrong here?
You may ask why I don't have a single database called ExtendedProperties with a single table in which each row is the UserID PK and the various extended properties are contained in columns. The simple answer is that some properties are themselves tables. Not every user has the same attributes in those tables. And I can't know ahead of time (a priori) what the full set of user extended property attributes is. So each user gets a table of their own.
Is there a better way to do this?

Trying to avoid polymorphic association in a schema for dynamic fields

I want to create a dynamic fields system. The idea is that the owner will be able to create dynamic fields for let's say, the customers of his company. The problem is that with the database structure that I came up with, requires the use of polymorphic association.
My structure is the following:
The fields table that consists of the following columns:
ID, FieldName, FieldType (The field type can be avoided, probably)
The field value tables (There are multiple value tables, one for every data type of the dynamic fields ex. A table to store the values that are DATETIMES, a table that stores the values that are DECIMALS and so on.).These tables have identical structure but with a different data type for their value column! They consist of the following columns:
ID, FieldID, CustomerID, FieldValue
Now, in order to get the field value I have to do a bunch of LEFT JOINs between the Value Tables and the Fields Table and keep only the value column that its value is not NULL, since that only one value column if any will have a value! Of course this isn't efficient at all and I am trying to avoid it. Any suggestions even if they require a completely different database structure at all are welcome. I am also using MySQL along with EntityFrameworkCore.

How to make 2 relations to the same table(using diferent columns) on dataset.relations?

I have a table clients and a table country, clients has 2 columns referencing country id (id of the country the client is from, and id from the counry the client wants its packages sent to), while dataset.relations is useful to fuse tables using 1 column(or more as long as they are diferent) i cant figure how to display a table that contains the info of the client, and the NAME of both countires corresponding to the ids.
For just the country of the client i go ass follows
billOrderDataset.Relations.Add("clientCountryRelation",countriesTableCopy.Columns("id"), clientTableCopy.Columns("countryId"))
clientTableCopy.Columns.Add("countryName",GetType(String), "Parent.countryName")
but after that i dont know how would i also add the name of the country to the column "deliveryCountryId" since there is already a relation using both tables and the id column from country, so bascially i would need something like
billOrderDataset.Relations.Add("clientCountryRelation2",countriesTableCopy.Columns("id"), clientTableCopy.Columns("DeliveryCountryId"))
clientTableCopy.Columns.Add("DeliveryCountryName",GetType(String), "Parent.countryName")
The answer is hidden in a paragraph inside the Remarks section in the documentation of the DataColumn.Expression property.
Parent/Child Relation Referencing
....
When a child has more than one
parent row, use Parent(RelationName).ColumnName. For example, the
Parent(RelationName).Price references the parent table’s column named
Price via the relation.
So, in other words, when you have more than one relation on the child table you need to explicitly give the name of the relation in the expression syntax
clientTableCopy.Columns.Add("countryName",GetType(String), "Parent(clientCountryRelation).countryName")
clientTableCopy.Columns.Add("DeliveryCountryName",GetType(String), "Parent(clientCountryRelation2).countryName")

What are "descendant tables" in Postgresql?

Database dumps from Postgresql use ALTER TABLE ONLY tablename instead of ALTER TABLE tablename which I am familiar with. I was curious what the ONLY keyword does, so I looked it up in the Postgresql documentation, and it says the following:
name
The name (optionally schema-qualified) of an existing table to alter. If ONLY is specified before the table name, only that table is altered. If ONLY is not specified, the table and all its descendant tables (if any) are altered. Optionally, * can be specified after the table name to explicitly indicate that descendant tables are included.
What are descendant tables?
PostgreSQL implements table inheritance, which can be a useful tool
for database designers. (SQL:1999 and later define a type inheritance
feature, which differs in many respects from the features described
here.)
Let's start with an example: suppose we are trying to build a data
model for cities. Each state has many cities, but only one capital. We
want to be able to quickly retrieve the capital city for any
particular state. This can be done by creating two tables, one for
state capitals and one for cities that are not capitals. However, what
happens when we want to ask for data about a city, regardless of
whether it is a capital or not? The inheritance feature can help to
resolve this problem. We define the capitals table so that it inherits
from cities:
CREATE TABLE cities (
name text,
population float,
altitude int -- in feet
);
CREATE TABLE capitals (
state char(2)
) INHERITS (cities);
In this case, the capitals table inherits all the columns of its
parent table, cities. State capitals also have an extra column, state,
that shows their state.
In PostgreSQL, a table can inherit from zero or more other tables, and
a query can reference either all rows of a table or all rows of a
table plus all of its descendant tables. The latter behavior is the
default.
Source: https://www.postgresql.org/docs/8.4/static/ddl-inherit.html
Descendant tables of a table are all tables that inherit from it, either directly or indirectly. So if table B inherits table A, and table C inherits table B, then:
Tables B and C are descendant tables of A.
Table C is a descendant table of B.
A query against a table (without ONLY) is a query against the table and all descendant tables. So, for example, a SELECT on a table with descendant tables is effectively a UNION of SELECT ... FROM ONLY across that table and all of its descendant tables. (In fact, if you inspect the query plan for a SELECT query on a table with descendants, you'll see that the plan is nearly identical to such a UNION query.)
If you are not using table inheritance, then the ONLY keyword has no effect on queries, as the set of descendant tables is empty.

decompose source data into new, many-to-many schema

I am using MS Access 2010 to do some transformations of data. Specifically, I need to create the data structure for a many-to-many relationship between concept (summarized by rxnconso.rxcui) and word (summarized by drugwords.id. Note that each value of drugwords.id needs to correspond with a unique value of name from the words table in the images below.). To accomplish this, I need to create two tables, drugwords and drugwordsConsoJunction, and also decompose the contents of an existing table words into the drugwords and drugwordsConsoJunction tables. The structure of the destination tables is:
drugwords table: (this table needs to be created)
id (autonumber pk needs to be created from distinct values of words.name)
name
drugwordsConsoJunction: (this table needs to be created)
word_id (fk to drugwords.id)
rxcui (fk to rxnconso.rxcui)
rxnconso (this table already exists):
rxcui
...other fields
The source table for this transformation is called words and has two columns; a value for rxcui, and a value for name. As you can see from the images below, there can be many name values for a given rxcui value. And the second image below shows that there can be many rxcui values for a given name value.
How do I write the SQL to transform words into drugwords and drugwordsConsoJunction, as per the above specifications?
I have uploaded a copy of the database to a file sharing site. You can download it at this link.
If the proposed [drugwords] table is already going to have unique values in its [name] column then you don't need an AutoNumber ID column, you can just use the [name] field as a Primary Key. In that case, the table that maps "words" to the corresponding [rxcui] values could be created by simply doing
SELECT DISTINCT rxcui, [name] INTO drugwordsConsoJunction FROM words
Then you can use the "words" themselves instead of introducing another layer of mapping from (distinct) "words" to (distinct) "IDs".