extending existing database - interfaces - mysql

I am working on extending the existing project which has been in production for couple of years and I need to extend a few existing entities, lets call them a,b,c,d.
When I now think about the designing of a database all the a,b,c,d should have some sort of inheritance, but changing the schema too much is impossible at this point.
Now all the a,b,c,d have their own primary keys but they all have to implement certain interfaces like - "bookmarkable", "taggable", "viewable" etc.
Would it make sense to keep creating tables like
a_saved, b_saved, c_saved, d_saved or a_tags, b_tags, c_tags etc to model the relation? But then again.. I would have to create THE SAME code to handle each of the scenarios where the only difference it's the table name!
I think better solution would be to create an new table - lets call it "object" and try to model some inheritance - for each entity create an entry in the "object" table and store that id in it's table and then create one relational table to map object_tag relation.
Does this sound like feasible solution or possibly error-prone and will bite me in the feature?

A similar solution to your second idea would be to create a single table that maps an extension by a combined (entity type, entity ID) key. See here for a sample schema and query: http://sqlfiddle.com/#!9/3c0235/1/0

Related

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.

How to create mysql table with many hasMany association in CakePHP?

I'm defining a completely new database. I have now faced a problem
which I would describe as "usual" but still could not find good
information from web. So here's the problem:
I have many tables in my database (which I would describe as guides) such as:
Skills
Places
Activities
and so on...
Now to all these guide types I'd like to add a comment feature and
other similar features like attaching images and videos. I have many guide types so I dropped the idea of having a separate comment image and video tables for each of them. I need one table for each of them.
The question is, what is the best way to achieve this? I have heard and read about 3 solutions and I'm not familiar with none of them.
I have read about using UUIDs would fix this problem but I'm not very familiar how they function. Could someone elaborate on that if that is the correct way to go? Something about UUIDs I read but not quite understood it.
Other thing I have read about is creating a hierarchial model "tree table" which would hold association links. More info at Managing Hierarchical Data in MySQL.
I have also read about creating object tables and using program like object inheritance inside MySQL in a similar way like the hierarchical model.
UUIDs sound most simple so I would appreciate help in there.
I don't know anything about how to use them. But here's how I thought it works - at least you'll get a hang of it what I'm trying to achieve here and how/what I'm misunderstanding about them:
I would create a new table: Guides which could have UUID field.
Then link all those guide types (Skills etc.) to guide table (Guide as parent and the other as child)
Parent and Child have both UUID fields and when creating a guide Parent and Child gets same UUID so they can be linked. Child also has its own Id field.
Then link comments to Guides by using UUID field that points to Guide plus separate id int field for comments.
Please tell me if this is correct way or is it total garbage and if so, how I should do it?
Have you though about using a normal hasMany relationship with a condition? Read about it here.
class Skill extends AppModel {
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'conditions' => array('Comment.type' => 1), // 1 for skills, 2 for places etc. or something like that.
)
);
}
Check http://cakeapp.com, create your DB layout there and download the SQL later.
I read more about UUIDs and since they allow application wide unique IDs I was able to do "inheritance" style of database.
I used my own prefix at the start of the every table name to avoid reserved table name collisions such as object. You can use any kind of prefix, for example: my_ and to use it like: my_object. All tables should use prefixes in this example.
So I created table Objects. It has the id field with Binary(36) type. Cake recognizes it as UUID field. Then I used 1:1 identifying relationships and inherited other tables from it, which I wanted to interact with others.
So I created 1:1 identifying relationship to Comments, Videos, Pictures table so that the table had the identifying foreign key being also a primary key.
Then I created Mappings table to which I used two 1:1 non-identifying relationships without primary key. This means this was really HABTM relationship to self.
Now this let me to "inherit" other tables from Objects table, like News table with again 1:1 identifying relationship. Then it was possible to link Comments, or anything other that has the 1:1 identifying relationship to Object, to News table by using the Mappings table.
I hope this will help others who are pondering this kind of solution aswell.

Using same type for LINQ-to-SQL mapping on different tables

I have a LINQ-to-SQL data context in which two tables exist with different names but identical structures. One table (called CallRecords) holds live/current data, and the other (CallRecordsArchive) holds older records - but with the same field names as the live one.
With the basic mapping LINQ to SQL creates two classes CallRecord and CallRecordsArchive - but since they are the same I'd like to avoid this if possible? That way I don't have to write two queries for each instance?
I did consider creating a JOIN view but with millions of rows in both tables it would be a performance nightmare.
The way I've dealt with this is to create an interface for the common aspects of both tables and have both of the generated classes from your data context implement that interface through the use of the a partial class definition. This way when you want to deal with the type as a single concept you can always refer to it as the interface.
try to use inherit for this issue
check this link for more details.
one more
I hope it is help you.

Creating an AssociationSetMapping for MySQL with the Entity Framework Designer?

I am trying to build an Entity Framework model for my database schema using EF4 and Visual Studio 2010. Since I am stuck using MySQL as our database (for now), I pretty quickly discovered that since MYISAM tables don't support foreign key constraints, the designer does not have any way to automatically create all the associations for you. It is easy enough to go through the model and build them all manually, but I ran into a problem trying to map a pure join table.
Normally if you are using SQL Server or some other database that supports Foreign Keys, the designer will create all the mappings for you and in the case of pure join tables will create an AssociationSetMapping such that the join table is entirely hidden in the model. Instead you end up with a Many to Many mapping between two two primary entities.
However I am at a loss as to how to create this kind of mapping manually? If I create a Many to Many association between my two entities, I end up with a regular Association, not an AssociationSetMapping. There does not appear to be a way to create one of these in the designer than I can figure out, and to tell it which join table is supposed to be used at the database level.
Am I missing something, and there is a way to do this?
If not, I suppose I have to hack the XML directly, but at this point it is not clear what I need to add to the XML files and where, in order to manually create the association set mapping?
Ok, I can answer this one myself. Once you create a many to many association with the designer, you DON'T set a referential constraint on it, but rather use the Mapping Details window to tell the association what table is the join table, and which keys map to which fields in the database. Simple enough once I figured it out :) But I could not find any good documentation on this.

Implementing custom fields with ALTER TABLE

We are currently thinking about different ways to implement custom fields for our web application. Users should be able to define custom fields for certain entities and fill in/view this data (and possibly query the data later on).
I understand that there are different ways to implement custom fields (e.g. using a name/value table or using alter table etc.) and we are currently favoring using ALTER TABLE to dynamically add new user fields to the database.
After browsing through other related SO topics, I couldn't find any big drawbacks of this solution. In contrast, having the option to query the data in fast way (e.g. by directly using SQL's where statement) is a big advantage for us.
Are there any drawbacks you could think of by implementing custom fields this way? We are talking about a web application that is used by up to 100 users at the same time (not concurrent requests..) and can use both MySQL and MS SQL Server databases.
Just as an update, we decided to add new columns via ALTER TABLE to the existing database table to implement custom fields. After some research and tests, this looks like the best solution for most database engines. A separate table with meta information about the custom fields provides the needed information to manage, query and work with the custom fields.
The first drawback I see is that you need to grant your application service with ALTER rights.
This implies that your security model needs careful attention as the application will be able to not only add fields but to drop and rename them as well and create some tables (at least for MySQL).
Secondly, how would you distinct fields that are required per user? Or can the fields created by user A be accessed by user B?
Note that the cardinality of the columns may also significantly grow. If every user adds 2 fields, we are already talking about 200 fields.
Personally, I would use one of the two approaches or a mix of them:
Using a serialized field
I would add one text field to the table in which I would store a serialized dictionary or dictionaries:
{
user_1: {key1: val1, key2, val2,...},
user_2: {key1: val1, key2, val2,...},
...
}
The drawback is that the values are not easily searchable.
Using a multi-type name/value table
fields table:
user_id: int
field_name: varchar(100)
type: enum('INT', 'REAL', 'STRING')
values table:
field_id: int
row_id: int # the main table row id
int_value: int
float_value: float
text_value: text
Of course, it requires a join and is a bit more complicated to implement but far more generic and, if indexed properly, quite efficient.
I see nothing wrong with adding new custom fields to the database table.
With this approach, the specific/most appropriate type can be used i.e. need an int field? define it as int. Whereas with a name/value type table, you'd be storing multiple data types as one type (nvarchar probably) - unless you complete that name/value table with multiple columns of different types and populate the appropriate one but that is a bit horrible.
Also, adding new columns makes it easier to query/no need to involve a join to a new name/value table.
It may not feel as generic, but I feel that's better than having a "one-size fits all" name/value table.
From an SQL Server point of view (2005 onwards)....
An alternative, would be to store create 1 "custom data" field of type XML - this would be truly generic and require no field creation or the need for a separate name/value table. Also has the benefit that not all records have to have the same custom data (i.e. the one field is common, but what it contains doesn't have to be). Not 100% on the performance impact but XML data can be indexed.