Using flat column or relationship in MySQL - mysql

I am designing a reward system for my game. I have a table called VirtualItem (VI) (key, display_name), the data contained could be (gd, gold), (dm,diomond). Then I have a Reward table (id, reward_items,etc)
Currently reward_items are a json array of VIs: [[{key: dm, count:5},{key:gd, count10]].There is a web portal allowing user to CRUD reward_items.
My question is, should I use the current flat structure, or add another layer in between and use reference in reward_items instead? Something like reward_items: set_id(referring VirtualItemSet table).
Apparently, using flat structure(json array) will make the query easy. But I probably also need to put dislay_name inside the JSON as well. In addition, when VI changes, its hard to update reward_items.
Using relationship makes the db schema more complex, and make backend operation on CRUDs operation of reward_items complicated as well.(need to create VirtualItemSet item on the fly etc). It also make query more complicated. But it will support dynamic change of VI.
Whats your opinion on this? Or there is a better database for this type of senario?
Thanks,
Chen

As you notice: If you use flat column you can't make sql join and keep data consistency by database for foreign keys. In my practice this decision always make problems in future. So i think better don't use flat columns.

Related

How to design a "dynamic" relational database

We're building a new piece of software for our company, where we want to manage our inventory.
The goal for the tool is to be customizable by the customer.
My part is mostly on the DB side. We have chosen MariaDB as our DB engine, and while we are working with the rather static functionality of a relational DB, we want to realize a rather dynamic solution.
Our chief programmer has explained to me the basics of the concept I shall implement into our DB:
We want a table which basically just consists of other tables.
Lets call it "maintable".
Maintable shall then reference its "attributes", which are the other tables.
For example, maintable references "Workstations".
"Workstations" then contains attributes like CPU, RAM, Drives, PSU etc..
And now comes the part which I didn't completely understand. The actual VALUES to these attributes in "Workstations" shall not be inserted into "Workstations". Instead, they are packed into another (junction?) table.
The reason for this approach is that the customer shall be able to customize the DB to his needs.
When the customer wants to add another attribute, he shall be able to do so. For example, if a new PSU now requires another attribute for an additional serial number, then the customer shall be able to simply create this new attribute in the front-end input form and then persist it to the DB.
If someone could point to good tutorials explaining this type of DB concept, then I would be glad as well! :=)

Right design to structurally ensure data consistency

In my current design, I have app_group, student and group_article:
To structurally ensure that a group_article is only associated with a student from that same group, the foreign keys "publisher" and "app_group" are taken from the join entity group_member (1) as opposed to having them issued from student and app_group individually. This way, someone with the right to insert new records into the database cannot introduce incoherent data such as adding an article that have been written by a student that isn't even in that group which would be poor design. Now, I want generalize this approach into multiple students or multiple groups. I now have group_message, group_message_in and group_message_out which is an inheritance chain (group_message is the base which is an abstract entity in Symfony, and both group_message_in and group_message_out extend it):
Initially, I was planning to embed the group foreign key on the base class (group_message) and have the sender/recipient (respectively on group_message_out and group_message_in) be taken from student directly:
However, this will leave the database vulnerable to incoherence as per the first example, eg: student from group A can be associated with a message that targets student from group B which is not desirable (only students from the same group can exchange group_message).
I'm well aware that I can amend this risk in code but I want a similar solution to (1) and to know if this is achievable with Doctrine since MySQL itself might have ways of solving a similar problem that aren't supported by Doctrine.
A relational solution to your problem would look something like this:
The integrity that you seek would be achieved by the PK-FK relationships and by assigning a student to a group using the groupName colums.
Your question then becomes something like "How can I use Doctrine to do the same thing?"
To the best of my knowledge Doctrine uses a set of PHP libraries to create what its proponents call a "persistence layer" that stores what it calls "Entities". With Doctrine, the term "Entity" is a synonym for "Class" in the OO paradigm.
In other words Doctrine stores classes in the data layer.
And now we can see the problem.
A relational schema is a structure of relations which is a completely different kind of artefact than a collection of classes.
The OO/Relational divide has been called an "impedance mismatch". Unfortunately this term obscures more than it reveals.
To quote from the Wikipedia article: "There have been some attempts at building object-oriented database management systems (OODBMS) that would avoid the impedance mismatch problem. They have been less successful in practice than relational databases however, partly due to the limitations of OO principles as a basis for a data model."
I suggest that you also review Ted Neward's article "The Vietnam of Computer Science."
This new answer shows the object-role model, the relational schema that it generates and the logic that is implied by the new constraint (shown by the red arrow)
The object- role model.
This is the logic that is asserted by the fact type Student(.id) is a member of Group(.name)
Now as the domain expert, you can read this verbalization and tell me whether it is True or False in your domain.
Please note that all I did as the modeler, was to change the constraint (shown by the red arrow) and the ORM tool called NORMA generated the new verbalization that you see here.
When the domain expert agrees that the model conforms to the requirements then it takes a few seconds to generate the SQL DDL that can then be used to create a new database schema in an RDBMS.

Adding tables via DAO to a database

As a general question which would really help me "connect the dots" with my studies.
I am currently doing exercises working with DAO and Learning how to add tables automatically. Although i have been working with databases for many years, i question, what type of scenerarios would it be vantagious to use this function. When is it necessary to add tables to a database in an automatic way? Up until now, in all my experiences the tables i need have Always been defined from the beginning and I cant think of a situation where I could of benefited from using this function. For example, i use frequently delete queries to help me clear tables and re-populate them, but when would it be necessary to actually "create" a new table"?
Yes, I have seen a scenario where new tables were created 'on the fly' (either via SQL create, or just DAO). With a shared database on a server, the application called for importing Excel data that a particular user was responsible for, so a table was created on the fly. Multiple users, changes in staff, need to keep data independent, etc. we could create their own table (name based on userid) that they had interfaces to do whatever they wanted with their own data. Not a typical scenario, but worked well for this application.

Manipulating data in a Microsoft Access table

I have a large database of client details, and I need to generate a totally new field of data based on a single other field. It would be a simple IF..THEN deal.
Example:
The source field has data that looks like this "BAR DIN" (Barrie Dinners) and I need to fill a new field with "Dinners".
From what I understand, Data Macros are the right way to do this, but I'd prefer not to buy Access 2010. There should be a way to do this with normal macros. This update only needs to be done once a year and can be done manually. I mostly looking for a way to avoid having to enter all that data manually for each customer.
Create a separate table to translate between the two:
source_field new_field
BAR DIN Barrie Dinners
FOO BROS Foo Brothers
Anytime you need to see the "new_field" values, JOIN that translation table to your original table (JOIN on source_field) to look them up. This approach is one of the fundamental reasons relational databases were created in the first place. This way your database will always be "up to date" without the need for any macros to populate a redundant field.

SQL - adding fields to query to sorty by

I'm working with a third party software package that is on it's own database. We are using it for the user management back bone on our application. We have an API to retrieve data and access info.
Due to the nature of information changing daily, we can only use the user_id as a pseudo FK in our application, not storing info like their username or name. The user information can change (like person name...don't ask).
What I need to do is sort and filter (paging results) one of my queries by the person's name, not the user_id we have. I'm able to get an array of the user info before hand. Would my best bet be creating a temporary table that adds an additional field, and then sorts by that?
Using MySQL for the database.
You could adapt the stored procedure on this page here to suit your needs the stored procedure is a multi purpose one and is very dynamic, but you could alter it to suit your needs for filtering the person table.
http://weblogs.asp.net/pwilson/archive/2003/10/10/31456.aspx
You could combine the data into an array of objects, then sort the array.
Yes, but you should consider specifically where you will make the temporary table. If you do it in your web application then your web server is stuck allocating memory for your entire table, which may be horrible for performance. On the other hand, it may be easier to just load all your objects and sort them as suggested by eschneider.
If you have the user_id as a parameter, you can create a user defined function which retrieves the username for you within the stored procedure.
Database is on different servers. For all purposes, we access it via an API and the data is then turned into an array.
For now, I've implemented the solution using LINQ to filter and out the array of objects.
Thanks for the tips and helping me go in the right direction.