I've almost completed my very complex project, then realized I had one issue still hanging me up. How do you (or is it even possible) to have the foreign key auto update (to reflect the parent) for each child table?
I guess I should mention the main site is built through Joomla. Everything I will be referring to in this post resides outside of Joomla but on the same domain, with the exception to the user profiles.
For instance...
I have table dataCompany that stores the company information. This table will be a child table to the userProfile table. Now, userProfile table has an auto-incremented column (user_id) and I created a column by the same name in dataCompany (but not auto-incremented). I want the user_id in dataCompany to auto fill to match that from userProfile.
The user will be logged in when entering data into dataCompany, which I thought would make it easier to autofill the user_id foreign constraint. However, I still get the invalid error.
Perhaps I'm missing something, but I was under the impression foreign keys were the only way to hold separate tables together.
EDIT:
I'm pretty sure I didn't explain what I'm doing very well.... so here's another try.
I have a website. The user will sign up for said website. That creates user_id in mysql database. I have a form the user will fill out, and the information will be stored in dataCompany. This table has primary key of companyID but also has column user_id. I want the data the user inserts into dataCompany to be associated with the user data tied together by user_id. Now, when the user signs up the user_id is auto-incremented. I can't have the user putting in their user_id when filling out their company information (as they don't know what it is)... that's where the 'auto update foreign key' comes from. I just want it to replicate what is already in the parent table (userData).
Related
Consider a simple situation in which there are 2 tables, named Users and WorkGroups.
A User's email address is the primary key in the users table.
A Workgroup_id is the primary key in the WorkGroup table.
A user can create multiple workgroups.
A user can be part of just 1 workgroup.
Under this given scenario I need to track which user created a workgroup.
What I have already done:
Have a variable named workgroup_id in the users table to know which workgroup the user belongs to. This is a foreign key to the workgroup_id in the Workgroup table.
Have a variable named user_email in the workgroup table to track which user created the workgroup. This is a foreign key to the user_email in the users table.
The problem which I am facing here is that this results in a cyclic reference between the users and the workgroups table. Since cyclic references anywhere in programming are a big no no.
How do I solve this? Is there a better design pattern which I am missing here?
EDIT:
As for whether the "circular references are a big no no" or not, conceptually they may not be but since there implementation is non universal in different databases, they still remain a valid problem. This is aggravated by the case when you have use an ORM, where the ORM support for your database limits the kind of database design you can have.
You need to allow at least one of the foreign keys to be NULL. This will allow you to create the first row in that table, leaving the foreign key empty as a placeholder. After you create the corresponding row on the other table, you update the foreign key in the first row.
You could also decide that this is OK as a permanent condition. If you create the first workgroup automatically before creating any users, that first workgroup doesn't really have a creator, so you could leave it set to NULL.
I'm using MySQL and have been planning out the database structure for a system I'm building out. As I've been going along, I started to wonder if it was acceptable to have a particular foreign key constraint in many different tables. From what I understand, it would be fine, as it makes sense. But I'd like to double check.
For example, I have a users table, and I use the user_id as a foreign key for many tables, sometimes multiple times in one table. For example, I have a one-to-one relationship with a user_settings table, which of course stores the user_id. And then I have a companies table, which alone has a few references to the user_id key. In this case, I have a column that keeps track of the user that created the company in the system (created_by), a column for the main contact (main_contact, who is also a user of the system), and there might be another reference. So that alone, already has the user_id key being used as a foreign key constraint 3-4 times.
Just to add another bit of info, I have a tasks table and that of course needs to reference the user_id to keep track of who it's assigned to, and I also have another column that keeps track of the user that created the task. That would be assigned_to and created_by, respectively.
There are more tables though that reference back to that key. I might be up to 8 references already. I do believe I've designed it properly so far, but based on what I've mentioned, does this sound fine?
Your foreign key usage seems fine to me - after all, you are simply representing logical relationships between your tables.
A user within your system interacts with the data in many ways, and to define these relationships your approach is the correct one.
The key point I think is that under a lot circumstances, you won't always want (or need) to make all the joins that represent your relationships - simply the ones that you need in that context.
As per my undestanding the way you are defining is fine i.e to use a user id to many tables as foreign key.
If your line:: I have a companies table, which alone has a few references to the user_id key doesn't mean that you are using multipe user_id in same table and I know you are not.
This seems like a desirable feature but I can't seem to figure out how I would do it while the foreign key is a part of the primary key (composite key).
The table is a simple junction table for a many to many relationship referencing User.id and Access.id referencing functions a user has access to:
Column | References
user user.id
access access.id
Therefore there can be many entries for each user and each access level. To simplify things for "superusers" I wanted to have a NULL value for access which would mean they have access to every page (this is the only way I could figure how to enter a value that didn't reference a row in the access table). The problem is MySQL won't allow a NULL value as a part of the primary key.
Is there a way around the NULL issue with primary keys or is there another way to reference every row (or no rows) in a foreign key? The only other way around this I can think of would be to disable the foreign key or have to add a row for every access.id in the table. Either of which would be undesirable.
Presumably you have a superuser flag on your user table. You could UNION a Cartesian join of each superuser and the set of available access IDs into whatever query you need this for.
Depending on what you're doing, you could also just not store the access for a superuser in the database and treat them differently in code - i.e. ignore the access check once you've established them as SU. Depends on your application though.
I think NULL is allowed and you can use it as a unique combination along with user.id. But I am not sure if this is a good way to do this. I mean you can store the super user setting in a column and use it in the code than here.
I have created 2 separate tables for admins and users in my database. I want to save user and admin login details (ip address, user_agent, connection time etc) into one table. Is the only solution to create two fields one for admin ids and other for user ids in this table (like below)?
CREATE TABLE login_detail (
id int NOT NULL AUTO_INCREMENT,
admin_id int,
user_id int,
ip_address ...
...
PRIMARY KEY (id),
FOREIGN KEY (admin_id) REFERENCES admin(id) ON DELETE RESTRICT ON UPDATE RESTRICT,
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
If an administrator logs in, his id will be stored in admin_id and user_id will be empty. If a user logs in, his id will be stored in user_id and admin_id will be empty. What do you suggest (generally)?
I believe that ermagana understood you were converting those two tables into one table, not accessing those two tables through the new, third table. At least, that is what I assumed until I saw your response. Am I correct? If so...
In general, there is really no reason why this wouldn't all be in one table with a bit-flag indicating admin authority, as ermagana responded. I believe that would be the most common implementation, though certainly not the only option.
Your implementation using three tables, as I understand it, will require extra coding and certainly more database activity. You will need to check if the user is a user and, if not, then check if the user is an admin. Also, how are you going to ensure that the same user isn't in both tables without extra coding and database activity? At least how I understand it, it appears inefficient and error-prone.
Perhaps I don't understand it at all. If so, please clarify.
I'm new to foreign key constraints. I will formulate a simple example to explain my situation.
I have a table user and a table entry. In user there is a user.firstEntry which is a foreign key to entry.EntryID. In entry there is a entry.userID which is a foreign key to the user.userID table. These IDs are all auto increment values.
Are cycles like that forbidden? Then I will have to change the design?
I am not able to insert some valid entry into both tables, because the first insert already says that there's a problem with the constraints. Auto commit is off.
What shall I do?
Thanks
Bit strange design, but you can do this :
When creating a User, set firstEntry to NULL.
Insert an Entry with that user's id.
Update Users and set firstEntry to the id of the inserted entry.
Both user and entry need the other to be already created beforehand. and since either cant be created without the other, you will have this problem IF foreign constraints check is on that is.
Whatever I can understand from your question, each user seems to have multiple entries. So your table design could look like Table_User(user_id(pk), user_name etc) and the entry table could be Table_Entry(entry_id(pk), entry_whatever,...,user_id(fk to user table)) As it seems the user is independent but the entries are dependent on users.
A foreign key constraint is supposed to prevent your from adding invalid data into the foreign key column.
In most cases it will check to see if the value actually exists in the specified table. Because you have a cycle in your user and entry table, when you attempt to create a entry it will check to see if the value of entry.userID exists in the user table. It will do the same when you attempt to add a new user, it will check the entry table for the value you entered for user.firstEntry. If both user and entry are new there is no way to link the two because of your cycle. A new entry record needs an existing user and a new user record needs an existing entry. When both tables are empty I don't think you will be able to satisfy the constraint.
I would suggest keeping the foreign key to userID in the entry table (since I'm assuming entries are linked to users) and finding some other way to represent a user's first entry. Maybe an user_entry_history table or something along those lines.
DISCLAIMER - It's been awhile since I messed with Database design.