How to relate two tables without a foreign key? - mysql

Can someone give a demo?
I'm using MySQL,but the idea should be the same!
EDIT
In fact I'm asking what's the difference between Doctrine_Relation and Doctrine_Relation_ForeignKey in doctrine?

I suspect what you are looking at would be to be map columns from one db table to another db table. You can do this using some string comparison algorithm. An algo like Levenstein or Jaro-Winkler distance would let you infer the "matching" columns.
For example, if db1.tableA has a column L_Name and db2.tableB has a column LastName, a string distance match would fetch you one measure. You can extend that by comparing the values in the rows to check if there is some consistency for example if the values in both tables contains: "Smith"s, "Johnson"s etc. you have a double-win.
I recently did something similar, integrating multiple large databases (one of them in a different language - French!) and it turned out to be quite a great experience.
HTH

You should use foreign keys to relate tables in MySQL, because it does not offer other ways to create relationships (such as references or nested tables in an object-oriented database).
See:
http://lists.mysql.com/mysql/206589
EDIT:
If you are willing to use Oracle, references and nested-tables are alternate ways to create relationships between tables. References are more versatile, so here is an example.
Since references are used in object-oriented fashion, you should first create a type and a table to hold objects of that type.
Lets create an object type of employee which has a reference to his manager:
CREATE TYPE employee_type AS OBJECT (
name VARCHAR2(30),
manager REF manager_type
);
We should also create an object type for managers:
CREATE TYPE manager_type AS OBJECT (
name VARCHAR2(30),
);
Now lets create two tables, one for employees and other for managers:
CREATE TABLE employees OF employee_type;
CREATE TABLE managers OF manager_type;
We can relate this tables using references. To insert an employee in employees table, just do this:
INSERT INTO employees
SELECT employee_type('Bob Jones', REF(m))
FROM managers m
WHERE m.name = 'Larry Ellison';
More info: Introduction to Oracle Objects

Well you could get around that by taking care of relationships in a server side language. Some database abstraction layers can handle this for you (such as Zend_Db_Table for PHP) but it is recommended to use foreign keys.
MySQL has InnoDB storage engine that supports foreign keys and also transactions.

Using a foreign key is the standard way of creating a relationship. Alternatives are pretty much nonexistent, as you'd have to identify the related rows SOMEHOW.
A column (or set of columns) which links the two tables IS a foreign key - even if it doesn't have a constraint defined on it (or even an index) and isn't either of the tables' primary key (although in that case you can end up with a weird situation where you can get unintended cartesian products when joining, as you will end up with a set vs set relationship which is probably not what you want)
Not having a foreign key constraint is no barrier to using a foreign key.

Related

Is it okay to use the same column as a primary key for different tables?

I am a total novice to this whole database world and I have a question. I am building a database for my final project for my masters class. The database includes cities, counties, and demographic data for the state of Colorado. The database ultimately will be used as a spatial database. At this point I have all my tables built in Access, and have a ODBC connection to PostgreSQL to import the tables after they are created. Access does not allow for shapefiles to be added to the database, PostgreSQL does.
My question is about primary keys, each of my tables in Access share an FIPS code (this code allows me to join the demographic data to a shapefile and display the data in ArcMap with the proper coordinates). I have a many demographic data tables with this FIPS code. Is it acceptable to set the FIPS as the primary key for each table? Or does each table need its own individual primary key that is different from the others?
Thanks for the help!
The default PK is “ID”, so there really no problem with using this default for all tables.
In fact it means for any table or code you write you can now always rest easy as to what the primary key is going to be.
And if you copy or re-name a table, then again you know the ID.
Some people do prefer having the table name as part of the PK, but that does violate normalizing of data since now your attaching an external attribute to that PK column.
However for a FK (foreign key), since the VERY definition of the column is an external dependency, then I tend to include the table name like this:
Customers_ID
And once again due to this naming convention, then you can always “guess” or “know” the name of a FK column (table name + ID).
At the end of the day, there is not really a convention on this issue. However I will recommend for all tables you create, you do allow access to create that default PK of “id”. This of course assumes your database design is not using natural keys. And the debate of natural keys vs surrogate key (an auto number pk “id”) has many pros and cons. You can google natural keys vs surrogate keys for endless discussions on this issue.

What is adding a new relationship to an existing table called?

In database terms, when i add a new foreign key, insert a record for that foreign key and update the existing record, what is the process called? My goal is to be able to find answers more effectively.
//create temporary linking key
alter table example add column example_foreign_key int unsigned null;
//contains more fields
insert into example_referenced_table (example_id, ...)
select id, ...
from example
join ...;
//link with the table
update example join example_referenced_table on example_id = example.id
set example.example_foreign_key = example_referenced_table.id;
//drop linking key
alter table example_referenced_table drop column example_id;
It looks like you're substituting one surrogate identifier for another. Introducing a surrogate key is sometimes (incorrectly) called normalization, so you may get some hits on that term.
In rare cases, normalization requires the introduction of a surrogate key, but in most cases, it simply decomposes a relation (table) into two or more, in such a way that no information is lost.
Surrogate keys are generally used when a natural or candidate key doesn't exist, isn't convenient, or not supported (e.g. composite keys are often a problem for object-relational mappers). For criteria on picking a good primary key, see: What are the design criteria for primary keys
There's little value in substituting one surrogate identifier for another, so the procedure you demonstrate has no proper name as far as I know, at least in the relational model.
If you mean to introduce a surrogate key as an identifier of a new entity set to which the original attribute is transferred, that's close to what Peter Chen called shifting a value set from the lower conceptual domain to the upper conceptual domain. You can find more information in his paper "The entity-relationship model - A basis for the enterprise view of data".
As for your question's title, it's not wrong to say that you're adding a relationship to a table (though that wording mixes conceptual and physical terms), but note that in the entity-relationship model, a relationship is represented by a two or more entity keys in a table (e.g. (id, example_foreign_key) in the example table) and not by a foreign key constraint between tables. The association of relationships with foreign key constraints came from the network data model, which is older than both the relational and entity-relationship models.

Using enumerations in mySQL Workbench

Im creating a database design in MySQL Workbench. I want to have a enumarated table which holds some standard values. The values of the enumaration table needs to be linked to a row in my other table. So i have a table called 'club' which holds a row 'club_soort'. The row 'club_soort' needs to relate to the enumaration table.
Also, I want to use my tables (when i'm ready with my database design) into phpMyAdmin.
I understand the concept of enumaration, but I can't implement it. I hope someone can help me!
Thanks!
Rather than using enumerations, you should use what's known as a lookup or reference table. This table would contain your enumerations and be referenced as a foreign key by the parent table.
As an example, this would look like:
parent_table
------------ club
id ----
club_soort ----------> soort
ENUM values cannot be linked to any MySQL structures. It can contain only static data.
Are you talking about primary keys?
Being a relational database, mysql uses primary keys and indexes to joint data the way you want to achieve.
Primary keys join tables in an efficient way, PK in the the origin or parent table and FPK, Foreign Primary Key in the related table.
When creating a table, in mysql workbench or phpmyadmin, define a primary key, just one per table and if needed indexes and if needed foreign keys.
Use union statements to join two or more tables.
Always use numeric keys data_type INT instead of natural, string keys. Also make then autoincrement and Not Null.
mysqlworkbench has an exporting tool, which allows you to export each created table, including their keys, indexes and cascading. You can copy and paste to create tables in phpmyadmin.

Modeling the storage of multiple data types that also have parent child relationships

I'm trying to design a MySQL database for a project I've started but I cannot figure out the best way to do it.
Its an OOP system that contains different types of objects all of which need to be stored in the database. But those objects also need to maintain parent child relationships with one another. Also I want the flexibility to easily add new data types once the system is in production.
As far as I can see I have three options, one that is pure relational, one which I think is entity attribute value (I don't properly understand EAV) and the last is a hybrid design that I've thought of myself, but I assume has already been thought of before and has a proper name.
The relational design would consist of two tables, one large table with columns that allowed it to store any type of object and a second table to maintain the parent child relationships of the rows in the first table.
The EAV design would have two tables, one being an EAV table with the three columns (Entity id, Attribute and Value), the second table would then relate the parent child relationships of these entities.
The hybrid design would have a table for each type of object, then a parent child relation table that would have to store the id of the parent, child and some sort of identifier of the tables that these id's come from.
I'm sure this problem has been tackled and solved hundreds of times before and I would appreciate any references so I can read about the solutions.
This is the only truly relational design:
CREATE TABLE Objects (
object_id INT AUTO_INCREMENT PRIMARY KEY,
parent_object_id INT,
-- also attribute columns common to all object types
FOREIGN KEY (parent_object_id) REFRENCES Objects (object_id)
);
CREATE TABLE RedObjects (
object_id INT PRIMARY KEY,
-- attribute columns for red objects
FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);
CREATE TABLE BlueObjects (
object_id INT PRIMARY KEY,
-- attribute columns for blue objects
FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);
CREATE TABLE YellowObjects (
object_id INT PRIMARY KEY,
-- attribute columns for yellow objects
FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);
But MySQL does not support recursive queries, so if you need to do complex queries to fetch the whole tree for instance, you'll need to use another method to store the relationships. I suggest a Closure Table design:
CREATE TABLE Paths (
ancestor_id INT,
descendant_id INT,
length INT DEFAULT 0,
PRIMARY KEY (ancestor_id, descendant_id),
FOREIGN KEY (ancestor_id) REFRENCES Objects (object_id),
FOREIGN KEY (descendant_id) REFRENCES Objects (object_id)
-- this may need additional indexes to support different queries
);
I describe more about the Closure Table here:
My answer to What is the most efficient/elegant way to parse a flat table into a tree?
My presentation Models for Hierarchical Data with SQL and PHP
My book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
Yes you can very well use the EAV design. It works for the application we created, although after about 3 years of refinement.
You can also use a generic table structure and use any particular table for a group of objects. Or just create one generic table for each object.
Which Table for which Object is part of a metadata repository.
If you use a val_int, val_string type of structure, you will have Null columns except where the value is stored. There are sparse matrix features of MS SQL which you might consider using. Disk size is somewhat cheap these days. So the only drawback you have vis-a-vis traditional structure is NxR rows (say R Attributes for the object) instead of N rows.
Other than that, few things to look out for are object instance GUIDs, dynamic sql generation...

Getting around the 32-relationship-per-table limit in Access

I am attempting to build a database for inventory control using a large number of tables and enforced relationships, and I just ran into the 32-relationship (index) limit for an Access table (using Access 2007).
Just to clarify: the problem isn't that the Employees table has 32 explicit indexes. Rather, the problem is the limitation on the number of times the Employee table can be referenced in FOREIGN KEY constraints. For example:
CREATE TABLE Employees (employee_number INTEGER NOT NULL UNIQUE)
;
CREATE TABLE Table01 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table02 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table03 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
...
CREATE TABLE Table30 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table31 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table32 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
An exception is thrown on the last line above, "Could not create index; too many indexes defined.
What options do I have to work around this limitation?
I've heard that creating a duplicate table with a 1:1 relationship is one method. I'm new to database design, so please correct me if I'm wrong; but given a table Employees with 31 indexes, I would create a table Employees2(with one field?) with a 1:1 relationship to Employees and relationships to this new table from any remaining relations in which EmployeeID is a foreign key. What's the best way to ensure the second table is populated alongside the first?
Is there another approach?
Based on the lack of information available, it seems this may be a rare problem with a properly-designed database, or the solution is common knowledge. Forgive the noob!
Update: Immediate consensus is that my design is borked or far too ambitious. This could very well be the case. However, I'd rather have a general design discussion within a separate question, so for the sake of argument, can someone answer this one? If the answer is simply "Don't ever do that" I'll have to accept it.
I've run into this limitation a number of times with my apps. And I can assure the other posters that my apps are very well designed.
One problem is that Access creates indexes due to relationships and lookup fields that aren't viewable on the main index property box but they are accessible via DAO collections. These indexes are frequently duplicate indexes to indexes you have created as well.
I have a tool consisting of several forms you import into your BE MDB that allows you to remove the duplicate indexes. As I haven't yet made this available on my website please email me for it.
I'd suggest just not defining all the relationships/indexes to implementing a 1:1 relationship to get around it. Neither solution is optimal, but the later is going to create a much higher maintenance burden and data anomaly potential.
I am not going to decry the design as quicky as some of the others, but it does have me intrigued. Could you list the fields of the employee table that are foreign keys? There is a good liklihood that some normalization is in order and maybe some of the smart people on SO could make some design suggestions to work around the issue.
It is hard for me to believe that an Employee table would need 32 indexes; if it actually does you should consider migrating to at least SQL Express.
... I would create a table
Employees2(with one field?) with a 1:1
relationship to Employees and
relationships to this new table from
any remaining relations in which
EmployeeID is a foreign key.
That is workable. Presumably your main table might have an Autonumber field as the primary key, or you generate an index number. Your Employees2 table obviously must echo that.
What's the best way to ensure the
second table is populated alongside
the first?
That depends somewhat on how you are adding records. But in general, of course you must comply with the rules for integrity. This usually comes down to appending to tables in the correct order and ensuring each record is saved before trying to add a related record elsewhere.