Create a compound Key including a lookup value - ms-access

I have not used access for many years, but need what I thought was a simple DB and struggling at early stage.
I have a table that represents objects that can belong to multiple systems and may have some different attributes between the systems.
So my initial idea was to have a table for Systems, a table for Objects, and a child table for Object Attributes.
My Objects table currently is 3 fields:
Key : Autogenerated
Object Name : Text
System : Lookup to system table
Object Name will not be unique as it can appear in multiple systems, so I want to create a unique compound key of the Object Name & System field. This key will be what joins this table to the child Object Attributes table.
My problem is that the System lookup field does not appear in the available fields to use when trying to create a compound key.
Could someone tell me where I am going wrong?

Related

Can I create a composite key with an extra character?

I'm building a new DB using MySQL to store lessons learned across a variety of projects. When we talk about this in the office, we refer to lessons by the Project Number and Lesson Number, i.e. PR12-81, where PR12 refers to the project and 81 refers to the specific lesson within that project. I want the primary key in my DB to have a hyphen in it as well.
When defining a composite key in SQL, I can make it reference the project and lesson but without the hyphen, i.e. PR1281. I've also considered creating a separate column of data type CHAR(1), putting a hyphen in every row and delcaring that the PK is made of 3 columns.
Is there another way that I can specify the primary key to be formatted in the preferred way?
Let your table's primary key be a nonsensical auto-increment number with no "meaning" whatsoever. Then, within that table, define two columns: project_number and lesson_number. If the two need to be unique, define a UNIQUE index encompassing the two fields.
Don't(!) create database keys which embed information into them, even if the business does so. If the business needs to refer to strings like PR12, so be it ... create a column to store the appropriate value, or use a one-to-many table. Use indexes as needed to enforce uniqueness.
Notice(!) that I've now described four columns:
The auto-increment based "actual" primary key, which contains no information.
The project_number column, probably a foreign key to a projects table.
Ditto the lesson_number. (With a UNIQUE composite index if needed.)
The column (or table) which contains "the string that the business uses."
Over time, business practices do change. And someday you just might .. no, you will... ... encounter a "business-used string" that was incorrectly assigned by the human-beings who do such things! Your database design needs to gracefully handle this. The schema I've described is so-called third-normal form. Do a Google-search on "normal forms" if you haven't already.

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.

Do I need a primary key for every table in MS Access?

I am new to MSAccess so I'm not sure about this; do I have to have a primary key for every single table in my database? I have one table which looks something like this:
(http://i108.photobucket.com/albums/n32/lurker3345/ACCESSHELP.png?t=1382688844)
In this case, every field/column has a repeating term. I have tried assigning the primary key to every field but it returns with an error saying that there is a repeated field.
How do I go about this?
Strictly speaking, Yes, every row in a relational database should have a Primary Key (a unique identifier). If doing quick-and-dirty work, you may be able to get away without one.
Internal Tracking ID
Some database generate a primary key under-the-covers if you do not assign one explicitly. Every database needs some way to internally track each row.
Natural Key
A natural key is an existing field with meaningful data that happens to identify each row uniquely. For example, if you were tracking people assigned to teams, you might have an "employee_id" column on the "person" table.
Surrogate Key
A surrogate key is an extra column you add to a table, just to assign an arbitrary value as the unique identifier. You might assign a serial number (1, 2, 3, …), or a UUID if your database (such as Postgres) supports that data type. Assigning a serial number or UUID is so common that nearly every database engine provides a built-in facility to help you automatically create such a value and assign to new rows.
My Advice
In my experience, any serious long-term project should always use a surrogate key because every natural key I've ever been tempted to use eventually changes. People change their names (get married, etc.). Employee IDs change when company gets acquired by another.
If, on the other hand, you are doing a quick-and-dirty job, such as analyzing a single batch of data to produce a chart once and never again, and your data happens to have a natural key then use it. Beware: One-time jobs often have a way of becoming recurring jobs.
Further advice… When importing data from a source outside your control, assign your own identifier even if the import contains a candidate key.
Composite Key
Some database engines offer a composite key feature, also called compound key, where two or more columns in the table are combined to create a single value which once combined should prove unique. For example, in a "person" table, "first_name" and "last_name", and "phone_number" fields might be unique when considered together. Unless two people married and sharing the same home phone number while also happening to each be named "Alex" with a shared last name! Because of such collisions as well as the tendency for meaningful data to change and also the overhead of calculating such combined values, it is advisable to stick with simple (single-column) keys unless you have a special situation.
If the data doesn't naturally have a unique field to use as the primary key, add an auto-generated integer column called "Id" or similar.
Read the "how to organize my data" section of this page:
http://www.htmlgoodies.com/primers/database/article.php/3478051
This page shows you how to create one (under "add an autonumber primary key"):
http://office.microsoft.com/en-gb/access-help/create-or-remove-a-primary-key-HA010014099.aspx
In you use a DataAdapter and a Currency Manager, your tables must have a primary key in order to push updates, additions and deletions back to the database. Otherwise, they will not register and you will receive an error.
I lost one week figuring that one out until I added this to the Try-Catch-End Try block: MsgBox(er.ToString) which mentioned "key". From there, I figured it out.
(NB : Having a primary key was not a requisite in VB6)
Not having a primary key usually means your data is poorly structured. However, it looks like you're dealing with summary/aggregate data there, so it's probably doesn't matter.

Relational database design

I'm trying to understand entities, tables and foreign keys. I have the following:-
AnObject - I have identified this as an entity type.
ID (Primary Key)
Description
State
DependsOn
Creator
Now State has only two values it can be [Alive, Dead]. However it could possibly have another in the future. It can however only be one or the other but it will likely change between the two.
Question:
Should State be its own entity type? Would it be an entity type or
just a table? Should State have a foreign key to AnObject or vice
versa? EG
State
ID (PK)
Description
AnObject_ID (Foreign Key references AnObject)
Question: The DependsOn attribute of AnObject can have multiple values of other AnObject entity types. Obviously a field cannot have multiple values but I'm not sure how to model this?
The Creator attribute of AnObject also takes up a strict number of values [Fred, Jim, Dean]. Should I have an entity type (table) for a Creator with a foreign key to AnObject ID? So, A Creator can create, 0, 1, m AnObjects but AnObject can only have one creator?
Thanks,
State could just be an enum field, unless you need users to be able to add other State values via a user interface, in which case you could use a lookup table (one-to-many relationship) as you suggested. I don't know what database you're using, but here's some info on the enum type in MySQL: http://dev.mysql.com/doc/refman/5.6/en/enum.html.
If you use a lookup table, then AnObject should have a field called StateID that points to the desired row in the State table.
It sounds like DependsOn is a many-to-many relationship. For that you will need a join table, e.g.:
Table: Dependencies
Primary key (called a "composite key" because it's made up of more than one field):
AnObjectParentID
AnObjectChildID
I've assumed that the dependencies are needed for a parent-child relationship but if that's not the case you might want to name the table or fields differently.
You can add extra tables for enumeration values with a foreign key from AnObject to it. State will probably be best represented as a single field of type varchar not null. You can have the primary key for a table be a varchar field - they don't have to be int type.
This will constrain the values but allow you to use reasonable syntax to query the thing (i.e. WHERE state = 'Alive' (although in this case I think you're prematurely abstracting things - I'd keep it simple and just have a simple bool column IsDead).
DependsOn is a one-way attribute (you presumably can't have A depend on B and also B depend on A). The real issue here is how you're intending to query these items and how many of them there will be. If you want to pull out the whole chain of dependencies at once and the chain is long, you want to avoid doing hundreds of individual queries to do that. What is your use case?

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...