How to refer to hardcoded values in code from the database? - mysql

In the (MySQL) database, I'm storing a view hierarchy, with each row in a table referring to a single view. There are several types of views, but they're stored in the same table.
In the application code, each type of view has its own class. Each row in the database instantiates one of these classes.
How should I refer to these classes from the database, so the application knows which class to use?
I can think of several possibilities:
Just specify the class name directly in the table, but this has the disadvantage of having to change lots of rows if the class name changes (which can be done in a single query if required).
Have a separate table storing class names, and use foreign keys to point to the row storing the correct class name. In this case, I could forgo having an ID field in this lookup table and instead have the class name as the primary key and target foreign key, and rely on a cascading UPDATE if the class name changes?
Are there better options available?

If I understand correctly you want to maintain an association between view-names and class-names.
Your bullets suggests, that there can be more than one view for the same class and both of your suggestions would work. The second bullet has the advantage that you can change the class name with a single update. But that doesn't buy you much, because as soon as more than just a single class-name changes, i.e. when the association itself changes, you need to update more than one row.
You might even create a separate table, holding this association. This would be the model for an n:m relationship, which is too general, so you'd have to place a unique constraint on the view-name. Essentially this will just factor out the concern of associating view-names with class-names and allow you to change this mechanism entirely without having to mess with your tables (except the one holding this association).
But actually I would not store any of this stuff in the database
(I also find it irritating that view-names are stored in the database and not in the application logic). The fact that there are class-names, should be of no concern to your database. This is application logic and it should be handled there. So what you need is a way to instantiate an object when the view-name is known. This looks like a classic factory to me. After all, if a class name changes, it is a change in the application code and life is easier, when all resulting changes lie in the application code as well.

Related

Access Automatically find matches and link after flat file import

I'm building an Access Database, and I'm a database design rookie. I have two tables, we'll call them Parent and Child. These tables represent a one-to-many relationship in the direction that one Parent can have many children. This data comes to us in the form of a flat file that we import the initial parent-child relationship. Later, we manually add other child relationships to the parent as situations demand.
When I do the initial flat file import, I bring in a unique identifier that I place into both the parent and child. My understanding is this type of duplication is poor database design because it's duplicative. I want to avoid this if I can. I can't think of another way to draw the link.
The other question I have, is, it is my understanding that it is best to use the AutoNumber primary key to do any database references. 1. Am I just wrong here? 2. Is it okay to use the unique identifier that I bring in with the flat file? 3. If it is bad design to bring in the duplicative data, is there a way, during the import process, to draw this link automagically to the Primary Key (I already have a macro on this import process to tie it to a user form, adding to this macro is not an issue)?
The purpose of this:
There is a subform on the parent record that should list any related child records in the child record database.
It would be a lot easier if you had provided a simple example.
If your data already contain IDs, example:
P:1,XX,YY
C:1,1,blah
C:1,2,fuh
P:2,zz,ww
C:2,1,doh
..then it would be next to impossible to match to autonumbering.
Either skip the ID completely, or if it's important, make the ID a different column and just use autonumber to make sure records are different.
So that master is
AutoID, PID, F1, F2,...
and child is
AutoID, ParentID, ChildID, FC1, FC2, ...
then match parent.PID onto child.ParentID.
If there is only ever 1 parent per child, you can set Parent.PID to "unique".
In the end, I just imported the unique record to both the parent and the child and used that. It's working great. It changed how I built my manual new child record creation process, but it all works now.

Best approach for migrating the "wrong" foreign key to the "correct" foreign key?

For context, I have a Laravel 6 project which made a rather odd choice, to put it mildly, on how to manage relationships when I inherited it.
I have a user object which has it's usual autoincrement id, as well as a "system_id" which is provided by an external system.
For most of the project, relationships involving a user object make use of their "id" field as the foreign key in the belongsTo() part of the relationship which is all well and good.
However, one many-to-many relationship, specifically the one used for the relationship between a user model and a group model, uses the user model's "system_id" field as the foreign key instead of the usual "id" field used everywhere else which is beginning to cause all kinds of development headaches, and is already in production.
So as part of a cleanup project of the system, I intend on migrating the pivot table to use the user model's "id" field. The challenge now is the following:
In a database-agnostic way, how to copy the matching id to the "user_id" foreign key field in the pivot table given a known "system_id".
How will it look in a migration? Is a migration even a good option or should it be done directly in the database instead?
Anything else I should account for?
Is this even a good idea in the first place or should we just live with it?
Obviously, a backup will be made and the whole thing will be tested in a test environment first before it's attempted in production.

SQL for one to one between a single table

I'd like to know what the best way of reflecting relations between precisely two rows from a single (my)sql table is?
Exemplified, we have:
table Person { id, name }
If I want to reflect that persons can be married monogamously (in liberal countries at least), is it better to use foreign keys within the Person:
table Person { id, name, spouse_id(FK(Person.id)) }
and then create stored procedures to marry and divorce Persons (ensuring mutual registration of the marriage or annulment of it + triggers to handle on_delete events..
or use a mapping table:
table Marriage {
spouse_a(FK(Person.id)),
spouse_b(FK,Person.id) + constraint(NOT IN spouse_a))
}
This way divorces (delete) would simply be delete queries without triggers to cascade, and marriage wouldn't require stored procedure.
The constraint is to prevent polygamy / multi-marriage
I guess the second option is preferred? What is the best way to do this?
I need to be able to update this relation on and off, so it has to be manageable..
EDIT:
Thanks for the replies - in practice the application is physical point-to-point interfaces in networking, where it really is a 1:1 relationship (monogamous marriage), and change in government, trends etc will not change this :)
I'm going to use a separate table with A & B, having A < B checked..
To ensure monogamy, you simply want to ensure that the spouses are unique. So, this almost does what you want:
create table marriage (
spouse_a int not null unique,
spouse_b int not null unique
);
The only problem is that a given spouse can be in either table. One normally handles this with a check constraint:
check (spouse_a < spouse_b)
Voila! Uniqueness for the relationship.
Unfortunately, MySQL does not support check constraints. So you can implement this using a trigger or at the application layer.
Option #1 - Add relationships structurally
You can add one additional table for every conceivable relationship between two people. But then, when someone asks for a new ralationship you forgot to add structurally, you'll need to add a new table.
And then, there will be relationship for three people at a time. And then four. And then, variable size relationships. You name it.
Option #2 - Model relationships as tables
To make it fool proof (well... never possible) you could model the relationships into a new table. This table can have several properties such as size, and also you can model restrictions to it. For example, you can decide to have a single person be the "leader of the cult" if you wish to.
This option requires more effor to design, but will resist much more options, and ideas from your client that you never thought before.

How to store modifications without changing the original DB record

I'm building an app in which users can create entities that are stored in my Entity table with some caracteristics like "space_below" and "width". Users can also create their own groups of entities by choosing amongst everybody's entities. Once they picked someone else's entity, I want them to be able to modify some caracteristics like the "width" and save these modifications for their own group. What would be to best way to do that in my DB?
First approach
Each time a user do a modification, create a new record (almost a duplicate) in the Entity table and then only refer to this new entity from the group where it was change.
In this case, I would need to add a column to my Entity table to differentiate original entites from copied entites.
Second approach
In any scenario, I will have a junction table between the Group table and the Entity table. In this junction table, I could add a "modification" column in which I store a JSON with the modifications. Something like { space_below: '8', width: '200' }. If there is no modficiation, the value of the column will be null.
I think I prefer the second approach since the first one involves a lot of duplicated data in the Entity table, but might not be aware of other implications.

One to many relationship

To start off, we have the following scenario (not exactly like this but for confidential reason I will not take the risk to explicitly describe the project) where let's say A person can Have Many home addresses and obviously an address belong to at most one person. This is pretty much a one to many relationship where there are 2 tables (Person and Addresses) with the second one holding a FK referencing the owner. But sadly i was told that my system should also allow users to enter Addresses first, so a FK that does not exist in the Person table yet. I came to the conclusion that i just have to drop that constraint. Do you thing it's a common thing to do? Furthermore I thought to maintain consistency even without FK (declared explicitly), if someone update the Person ID, since i dont want the user to do it in both table, is it possible to create a Trigger (I'm using Mysql server) that will update the second table automatically (if that person has an address)? If yes, any hint to how to write that (I'm not familiar with triggers)
You can maintain the 1:N relationship by creating the kind of intermediate table normally associated with M:N relationships but adding a uniqueness constraint on the address referencing field; alternatively, you can just make address' reference to person nullable, making it an optional reference.
[Edit]
Scripts from MySQL dump wrap their contents with something like:
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=0;
....
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
As you can probably guess, it temporarily turns off foreign key checks to allow inserting interdependent data out of order. However, you should be sure of the trustworthiness of the import data as I believe it does not recheck the data when turned back on (so it can allow data that violates FK constraints to persist).
If you need the ability to add "address" before "person" with user entered data, then you are back the original situation of needing optional keys or another table; or just not actually saving the "address" info (but instead holding it locally in the data entry program) until after the "person" info is sufficient/complete.