In generating a Linq to SQL class, how can I define a complex relationship? - sql-server

I have two views: one is a normal view built from one table with an integer ID and other columns for the record (let's call it View1). I have another View (View2), which has an integer ID column and a second column named "table" (type: varchar). That second column contains the name of the table to which the ID column is related: So, if View2 contains an ID of 999 and its "table" column contains the value "View1", that means the record referenced is ID 999 from View1.
Far as I can tell, DBML only allows for one-to-one or one-to-many relationships based on explicit column references; I'd rather express the relationship as a one-to-one based on the ID column AND View1.table being equal to "View2".
Is this possible? I know I can simply do an outer join in the linq query, but I'd rather avoid that if possible. Thanks!

It's not possible. The linq2sql mapper allows for mapping explicit foreign key relations, but if you don't actually have a foreign key relationship in the database, it's not possible for L2S to "infer" the relation in any way.

Related

Unable to use the dimension table as a nested table in SQL server data tools

I have the following relationship set up between my fact table and dimension tables.
When trying to create a data mining structure, I had to choose the dimension table Dimension_Status as a nested table for the fact table as I'm trying to predict the probability of "TimelyResponse" in the fact table using the "IssuedVia" in the Dimension_Status table. But when trying to do so, I get the following error.
Dimension_Status table cannot be used as a nested table because it does not have a many-to-one relationship with the case table. You need to create a many-to-one relationship between the two tables in the data source file
What am I doing wrong here? Why am I getting this error though my dimension tables are maintaining a many to one relationship with the fact table? Please advice.
I could be completely missing the mark here (I haven't done a great deal of data-mining using SSAS), but from what I can tell nested tables are the "Many" side of a many-to-many relationship. From the MSDN article on Nested Tables it shows the "Products" table as being nested in the "Customer" table, because each Customer can have many Products:
In this diagram, the first table, which is the parent table, contains
information about customers, and associates a unique identifier for
each customer. The second table, the child table, contains the
purchases for each customer. The purchases in the child table are
related to the parent table by the unique identifier, the CustomerKey
column. The third table in the diagram shows the two tables combined.
A nested table is represented in the case table as a special column
that has a data type of TABLE. For any particular case row, this kind
of column contains selected rows from the child table that pertain to
the parent table.
So it looks like nested tables are not what you're after - unfortunately I'm not familiar enough with the SSA data mining tools to recommend the appropriate approach (unless switching them around and making the DimStatus table your Case table and Fact_CustomerComplaints your Nested table will work in your situation.)
To put it simply, your arrows are backwards.
Reverse the relationships so the tables you want to be nested are pointing to your Fact_ table.
Like so:

Is there a name for a type of database table that that forms a 0..1 relationship with another table?

Let's say I have a table called Data, and another table called ExtraData. ExtraData has a foreign key reference to Data's primary key. ExtraData is not guaranteed to have a row for every row in Data, but it can at most have one row associated to a row in Data. Is there a proper term for the type of table ExtraData is?
Bonus points on the answer if someone can point me to a resource that describes proper terminology in data modeling like this.
Thank you.
Data is called Base Table and ExtraData is called Derived Table.
Search Wikipedia page of Weak Entity for this term.
When sub-type relationships are rendered in a database, the super-type
becomes what is referred to as a base table. The sub-types are
considered derived tables, which correspond to weak entities.

Duplicating columns in an inheritance model

I have two tables that model an inheritance relationship. This is expressed by a foreign key constraint on Derived.Id referencing Base.Id. Some columns in Base are essentially duplicated in Derived so they can be referenced in unique constraints and compound foreign keys. I would like to ensure the values for these columns are the same in both tables. Ideally, this would be done with a compound foreign key on Id + the column. But this prevents the values from being changed--it's a catch-22 scenario.
How could I ensure these columns have the same values in both tables and allow them to be updated? I have complete flexibility, so I can change the tables' schemas or do whatever else is necessary to make this possible.
I would only keep the columns in one of the tables, base if it applies to all objects.
Can you give an example of the necessity of duplicating your columns with a concrete example, like base = car, has VIN, derived = myCar, has VIN.
Also, if the duplicated columns are part of the keys, use cascade update.
Rather than have 2nd table, I would just have all of the columns Derived needs inside the Base table and set those columns to be nullable. If you add a discriminator column as well to determine if the particular record represents a Base object or a Derived object, you are all set.
You can set up whatever constraints you need and don't have to deal with duplicate data getting out of sync, which is why the single-table-per-hierarchy is the default method Hibernate (and NHibernate) use for mapping inheritance.

Tables with a common primary key

What's the term describing the relationship between tables that share a common primary key?
Here's an example:
Table 1
property(property_id, property_location, property_price, ...);
Table 2
flat(property_id, flat_floor, flat_bedroom_count, ...);
What you have looks like table inheritance. If your table structure is that all flat records represent a single property but not all property records refer to a flat, then that's table inheritance. It's a way of modeling something close to object-oriented relationships (in other words, flat inherits from property) in a relational database.
If I understand your example correctly, the data modeling term is Supertype/Subtype. This is a modeling technique where you define a root table (the supertype) containing common attributes, and one or more referencing tables (subtypes) that contain varying attributes based on the entities being modeled.
For example, you could have a Person table (the supertype) containing columns for attributes pertaining to all people, such as Name. You could then have an Employee table (the subtype) containing attributes specific to employees only, such as rate of pay and hire date. You could then continue this process with additional tables for other specializations of Person, such as Contractor. Each of the subtype tables would have a PersonID key column, which could be the primary key of the subtype table, as well as a foreign key referencing the Person table.
For additional info, search Google for "supertype and subtype entities", and see the links below.
http://www.learndatamodeling.com/dm_super_type.htm
http://technet.microsoft.com/en-us/library/cc505839.aspx
There isn't a good name for this relationship in common database terminology (as far as I know). It's not a one-to-one relationship because there isn't guaranteed to be a record in the "extending" table for each record in the main table. It's not a one-to-many relationship because there a maximum of one record allowed on what would otherwise be the "many" side of the relationship.
The best I can do is a one-to-one-or-none or a one-to-one-at-most relationship. (I will admit to sloppy terminology myself — I just call it a one-to-one relationship.)
Whatever you decide to call it, you can model it properly and maintain integrity in your database by making the property_id column in property a PK and the property_id column in flat a PK and also an FK back to property.
"Logic and Databases" advances the term "at most one to at most one" for this kind of relationship. (Note that it is insane to assign names to tables on account of which relationships they participate in.)
Beware of the people who have suggested things like "foreign key", "table inheritance", brief, all the other answers given here. Those people are making assumptions that you have not explicitly stated to be valid, namely that one of your two tables will be guaranteed to contain all key values that appear in the other.
(Disfunctionality of the site prevents me from adding this as a comment in the proper place.)
"How would you interpret "...that share a common primary key?" "
I interpret that in the only reasonable sense possible: that within table1, attribute values for the primary key are guaranteed to be unique, and that within table2, attribute values for the primary key are guaranteed to be unique. And that furthermore, the primary key in both tables has the same [set of] attribute names, and that the types corresponding to the primary key attribute[s] are also pairwise the same. Nothing more and nothing less.
In particular, "sharing a primary key" means "having a primary key in common", and that means in turn "having a certain 'internal uniqueness rule' in common", but that commonality guarantees in no way that a primary key value appearing in one table must also appear in the second table.
"Can you give an example involving two tables with shared primary keys where one table wouldn't contain all the key values that appear in the other?" "
Table1: column A of type integer, primary key A
Table2: column A of type integer, primary key A
Rows in table1: {A:1}. Satisfies the primary key for table1.
Rows in table2: {A:2}. Satisfies the primary key for table2.
Convinced ?
"Foreign key"?

Foreign key referencing composite table

I've got a table structure I'm not really certain of how to create the best way.
Basically I have two tables, tblSystemItems and tblClientItems. I have a third table that has a column that references an 'Item'. The problem is, this column needs to reference either a system item or a client item - it does not matter which. System items have keys in the 1..2^31 range while client items have keys in the range -1..-2^31, thus there will never be any collisions.
Whenever I query the items, I'm doing it through a view that does a UNION ALL between the contents of the two tables.
Thus, optimally, I'd like to make a foreign key reference the result of the view, since the view will always be the union of the two tables - while still keeping IDs unique. But I can't do this as I can't reference a view.
Now, I can just drop the foreign key, and all is well. However, I'd really like to have some referential checking and cascading delete/set null functionality. Is there any way to do this, besides triggers?
sorry for the late answer, I've been struck with a serious case of weekenditis.
As for utilizing a third table to include PKs from both client and system tables - I don't like that as that just overly complicates synchronization and still requires my app to know of the third table.
Another issue that has arisen is that I have a third table that needs to reference an item - either system or client, it doesn't matter. Having the tables separated basically means I need to have two columns, a ClientItemID and a SystemItemID, each having a constraint for each of their tables with nullability - rather ugly.
I ended up choosing a different solution. The whole issue was with easily synchronizing new system items into the tables without messing with client items, avoiding collisions and so forth.
I ended up creating just a single table, Items. Items has a bit column named "SystemItem" that defines, well, the obvious. In my development / system database, I've got the PK as an int identity(1,1). After the table has been created in the client database, the identity key is changed to (-1,-1). That means client items go in the negative while system items go in the positive.
For synchronizations I basically ignore anything with (SystemItem = 1) while synchronizing the rest using IDENTITY INSERT ON. Thus I'm able to synchronize while completely ignoring client items and avoiding collisions. I'm also able to reference just one "Items" table which covers both client and system items. The only thing to keep in mind is to fix the standard clustered key so it's descending to avoid all kinds of page restructuring when the client inserts new items (client updates vs system updates is like 99%/1%).
You can create a unique id (db generated - sequence, autoinc, etc) for the table that references items, and create two additional columns (tblSystemItemsFK and tblClientItemsFk) where you reference the system items and client items respectively - some databases allows you to have a foreign key that is nullable.
If you're using an ORM you can even easily distinguish client items and system items (this way you don't need to negative identifiers to prevent ID overlap) based on column information only.
With a little more bakcground/context it is probably easier to determine an optimal solution.
You probably need a table say tblItems that simply store all the primary keys of the two tables. Inserting items would require two steps to ensure that when an item is entered into the tblSystemItems table that the PK is entered into the tblItems table.
The third table then has a FK to tblItems. In a way tblItems is a parent of the other two items tables. To query for an Item it would be necessary to create a JOIN between tblItems, tblSystemItems and tblClientItems.
[EDIT-for comment below] If the tblSystemItems and tblClientItems control their own PK then you can still let them. You would probably insert into tblSystemItems first then insert into tblItems. When you implement an inheritance structure using a tool like Hibernate you end up with something like this.
Add a table called Items with a PK ItemiD, And a single column called ItemType = "System" or "Client" then have ClientItems table PK (named ClientItemId) and SystemItems PK (named SystemItemId) both also be FKs to Items.ItemId, (These relationships are zero to one relationships (0-1)
Then in your third table that references an item, just have it's FK constraint reference the itemId in this extra (Items) table...
If you are using stored procedures to implement inserts, just have the stored proc that inserts items insert a new record into the Items table first, and then, using the auto-generated PK value in that table insert the actual data record into either SystemItems or ClientItems (depending on which it is) as part of the same stored proc call, using the auto-generated (identity) value that the system inserted into the Items table ItemId column.
This is called "SubClassing"
I've been puzzling over your table design. I'm not certain that it is right. I realise that the third table may just be providing detail information, but I can't help thinking that the primary key is actually the one in your ITEM table and the FOREIGN keys are the ones in your system and client item tables. You'd then just need to do right outer joins from Item to the system and client item tables, and all constraints would work fine.
I have a similar situation in a database I'm using. I have a "candidate key" on each table that I call EntityID. Then, if there's a table that needs to refer to items in more than one of the other tables, I use EntityID to refer to that row. I do have an Entity table to cross reference everything (so that EntityID is the primary key of the Entity table, and all other EntityID's are FKs), but I don't find myself using the Entity table very often.

Resources