Relate two MySQL tables? - php

I'm kind of stuck in a pickle trying to make two separate database tables related to each other by two columns.
On my website I have a set of classes along with a set of objectives which belong to each class. Classes are stored in their own database table, and so do the objectives in their own table as well.
I want the user to be able to manually set the start and end dates for any objective for an active class, and when this happens it needs to update in the database as well. My trouble comes from trying to visualize how this is all supposed to happen, and how the tables in the database should handle this. All help is greatly appreciated on this. Thanks
EDIT: This is my current table design. (I don't know how to make a proper table on here yet, so I'll just create a rough draft of the design.)
Classes
class_id | instr_id | class_name | start_date | end_date |
1 | 1 | Class1 | 2013-05-10 | 2013-05-30 |
2 | 2 | Class2 | 2013-05-10 | 2013-05-30 |
3 | 3 | Class3 | 2013-05-10 | 2013-05-30 |
.. and so on for each class.
Objectives
class_id | objective_id | start_date | end_date |
1 | 1 | 2013-05-10 | 2013-05-30 |
1 | 2 | 2013-05-10 | 2013-05-30 |
1 | 3 | 2013-05-10 | 2013-05-30 |
2 | 1 | 2013-05-10 | 2013-05-30 |
2 | 2 | 2013-05-10 | 2013-05-30 |
2 | 3 | 2013-05-10 | 2013-05-30 |
... and so on so every class has every objective_id, assuming each
class has only 3 objectives.
I really hope this helps clarify some things.

Where there is a many-to-many relationship between two relational tables (as described here - one objective can be set for many classes, and each class can have many objectives), this should normally represented by a link table, which will have a many-to-one relationship with each of the parent tables.
Here, the link table could be called something like objective_assigned (as shortened form of "Objective assigned to Class") - it might have a structure like:
class_id
objective_id
start_date
end_date
- with a compound primary key on class_id and objective_id.
I would also expect an Objective table to exist, with a primary key of objective_id and a column to hold the objective title/name.

Related

Database model for a multilanguage translation module

I need to design a db model for a backend module where user can translate page content into multiple languages. The things that will be translated are basic words, phrases, link names, titles, field names, field values. They should also be grouped so i can find them by group name. For example if there is a select field on page with different colors as options then i should be able to select all of them by group name.
So here is what i have at the moment:
lang
+----+---------+
| id | name |
+----+---------+
| 1 | english |
| 2 | german |
+----+---------+
lang_entity
+----+------------+-------------+-------+-------+
| id | module | group | name | order |
+----+------------+-------------+-------+-------+
| 1 | general | | hello | 0 |
| 2 | accounting | colorSelect | one | 1 |
| 3 | accounting | colorSelect | two | 2 |
| 4 | accounting | colorSelect | three | 3 |
+----+------------+-------------+-------+-------+
lang_entity_translation
+----+---------+----------------+-------------+
| id | lang_id | lang_entity_id | translation |
+----+---------+----------------+-------------+
| 1 | 1 | 1 | Hello |
| 2 | 2 | 1 | Guten tag |
| 3 | 1 | 2 | One |
| 4 | 2 | 2 | Ein |
| 5 | 1 | 3 | Two |
| 6 | 2 | 3 | Zwei |
| 7 | 1 | 4 | Three |
| 8 | 2 | 4 | Drei |
+----+---------+----------------+-------------+
So lang table holds different languages.
Table lang_entity has entities that can be translated for different languages.
Module row is just to group them by page modules in the backend translating module. Also this gives me possiblity to have entities with same name for different modules.
Group as mentioned is needed for selects and maybe some other places where multiple values are going to be used. This also gives me an option to allow user to add and order entities in one group.
And table lang_entity_translation holds the translations for each entity in each language.
So my question is are visible flaws in this kind of a design? Would you reccomend something different?
Also a bonus question: I really dont like the lang_entity table name, do you have a better idea of a table name that would hold all the words/phrases that are translated? :)
Edit: similar, but not a duplicate. The linked question is about translating dynamic products and having a seperate table for each translated type. Im talking about translating whole page content, including groups in a single table.
I don't understand the order column of lang_entity, but then I probably don't need to.
The setup looks sane, but make sure you add foreign key constraints from lang_entity_translation to language and lang_entity.
As for naming, I would call the table phrase or translatable.
We had similar situation. This was 7 years before.
We had different column for different language. Like for name we had
Name_Eng,Name_Ger,Name_Spa .We had 7-10 language.
We had common id for name for all language.
Based on the Language selection from UI we passed the language code to Back end In the Stored proc it was appended to the column Name
Example, we will be passing "Eng" if English is selected and we form the column name as Name_Eng and fetch the data. we were using dynamic query.

Laravel get only models with current version

I have implemented custom model versioning in Laravel Framework. There is couple of columns handling it in the database table: sibling_id (links model's different versions together), version, accepted and validFrom.
For example:
| id | sibling_id | version | accepted | validFrom | ... |
|----|------------|---------|----------|------------|-----|
| 1 | 1 | 1 | 1 | 2017-12-01 | |
| 2 | 1 | 2 | 1 | 2018-06-01 | |
| 3 | 2 | 1 | 1 | 2017-12-10 | |
| 4 | 2 | 2 | 0 | 2017-12-28 | |
| 5 | 3 | 1 | 0 | 2017-12-01 | |
What I mean with current model:
model having the biggest version number within accepted and valid modals
OR version 1 if there isn't any other versions
I would like to have some way to get normally only current model grouped by sibling_id (so within this example the collection should include models 1, 3 and 5). This should work like same way than Laravel's withTrashed() function so that I can include all if I want to (for example version history).
Maybe this can be done somehow with the scopes but I felt it complicated because of the "sibling grouping" and another complex filters so I ended up to ask here.
Thanks in advance.
I think a SQL View would be easier to work with, rather than build the query with Laravel.
I'd build a view implementing the query something along:
select t.* from table as t
join (select sibling_id, MAX(version) as version from table group by sibling_id) as grouped
on grouped.sibling_id = t.sibling_id and t.version = grouped.version;
Then map another eloquent model for the view in Laravel. This way, you can just select from the table if you want to get all, or from the view if you want "unique" records.

Mysql join query multiple values

I have a table called facility.
Structure looks as follows:
id | name
---------
1 | Hotel
2 | Hospital
3 | medical shop
I have an other table which is taking data from the above table and keeping multiple values in one column. View looks like below:
id | facilities
---------------
1 | Hospital~~medical shop~~Hotel
2 | Hospital~~Hotel
3 | medical shop~~Hotel
If I want to join these two tables how does the query look like?
I tried this, but it didn't work:
select overview.facilities as facility
from overview join facility on facility.id=overview.facilities;
you can do this with a bit of hackery
select o.facilities as facility
from overview o
join facility f on find_in_set(f.facilities, replace(o.facilities, '~~', ','));
I would highly recommend you change the way you are storing data. currently it is considered un normalized and that quickly becomes a monster to deal with
you should change your table structure to look something more like this
+----------+--------------+
| facility |
+----------+--------------+
| id | name |
+----------+--------------+
| 1 | Hotel |
| 2 | Hospital |
| 3 | medical shop |
+----------+--------------+
+-----------+-------------+
| overview |
+-----------+-------------+
| id | facility_id |
+-----------+-------------+
| 1 | 2 |
| 2 | 3 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 3 |
| 7 | 1 |
+-----------+-------------+
Code Explanation:
basically you are wanting to find the matching facilities in the overview. one handy function MySQL has is FIND_IN_SET() that allows you to find an item in a comma separated string aka find_in_set(25, '11,23,25,26) would return true and that matching row would be returned... you are separating your facilities with the delimiter ~~ which wont work with find_in_set... so I used REPLACE() to change the ~~ to a comma and then used that in the JOIN condition. you can go from here in multiple ways.. for instance lets say you want the facility id's for the overview.. you just add in the select GROUP_CONCAT(f.id) and you have all of the id's... note if you do that you need to add a GROUP BY at the end of your query to tell it how you want the results grouped

Database design with undetermined data

Recently I have been planning a system that allows a user to customize and add to a web interface. The app could be compared to a quiz creating system. The problem I'm having is how to design a schema that will allow for "variable" numbers of additions to be made to the application.
The first option that I looked into was just creating an object for the additions and then serializing it and putting it in its own column. The content wouldn't be edited often so writing would be minimal, reads however would be very often. (caching could be used to cut down)
The other option was using something other than mysql or postgresql such as cassandra. I've never used other databases before but would be interested in learning how to use them if they would improve the design of the system.
Any input on the subject would be appreciated.
Thank you.
*edit 29/3/14
Some information on the data being changed. For my idea above of using a serialized object, you could say that in the table I would store the name of the quiz, the number of points the quiz is worth and then a column called quiz data that would store the serialized object containing the information on the questions. So overall the object could look like this:
Questions(Array):{
[1](Object):Question{
Field-type(int):1
Field-title(string):"Whats your gender?"
Options(Array):{"Female", "Male"}
}
[2](Object):Question{
Field-type(int):2
Field-title(string):"Whats your name?"
}
}
The structure could vary of course but generally i would be storing integers to determin the type of field in the quiz and then a field to hold the label for the field and the options (if there are any) for that field.
In this scenario I would advise looking at MongoDB.
However if you want to work with MySQL you can think about the entity-attribute-value model in your design. The EAV model allows you to design for entries that contain a variable number of attributes.
edit
Following your update on the datatypes you would like to store, you could map your design as follows:
+-------------------------------------+
| QuizQuestions |
+----+---------+----------------------+
| id | type_id | question_txt |
+----+---------+----------------------+
| 1 | 1 | What's your gender? |
| 2 | 2 | What's your name? |
+----+---------+----------------------+
+-----------------------------------+
| QuestionTypes |
+----+--------------+---------------+
| id | attribute_id | description |
+----+--------------+---------------+
| 1 | 1 | Single select |
| 2 | 2 | Free text |
+----+--------------+---------------+
+----------------------------+
| QuestionValues |
+----+--------------+--------+
| id | question_id | value |
+----+--------------+--------+
| 1 | 1 | Male |
| 2 | 1 | Female |
+----+--------------+--------+
+-------------------------------+
| QuestionResponses |
+----+--------------+-----------+
| id | question_id | response |
+----+--------------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | Fred |
+----+--------------+-----------+
This would then allow you to dynamically add various different questions (QuizQuestions), of different types (QuestionTypes), and then restrict them with different options (QuestionValues) and store those responses (QuestionResponses).

Database table structure query

Just a quick query on the best databased structure to go with for a small application, [ the database will be SqlLite or MySql and the app written in PHP if that helps]
Basically my issue is that entries will have many options and these will be likely to be added to and removed so editing the db structure is probably not the best idea. I am just wondering what the best way to store this options to the data base. In similar situations in the past I have achieved this by storing the data serialised or in JSON format to a table row, but I am wondering if this is the best option, any advice would be great.
The application is map based where a user can add/remove markers, the markers have types [ eg shop, school, hospital etc. ] the user can also add and remove types. In addition to this the use can create map views eg a map where only the school and hospitals are visible.
It is a bit hard to describe but here is a go describing the [ simplified ] table structure
markers
+---------+-----+-----+--------+-----------+
|markerID | lat | lng | typeID | name |
+---------+-----+-----+--------+-----------+
|1 | 52 | -9 | 1 | A School |
|2 | 52 | -9 | 2 | A Shop |
|3 | 52 | -9 | 1 | B School |
|4 | 52 | -9 | 3 | A Hospital|
+---------+-----+-----+--------+-----------+
marker types
+-------+-------------+--------------+
|typeID | name | icon |
+-------+-------------+--------------+
|1 | Schools | school.png |
|2 | Shops | shop.png |
|3 | Hospitals | hospitals.png|
+-------+-------------+--------------+
map view
+------+---------------------+---+
|mapID | name | ??|
+------+---------------------+---+
|1 | Schoool & Shops | ??|
|2 | Hospitals & Schools | ??|
+------+---------------------+---+
So my question is basically, what is the best way to store the information that mapID #42 should display markers with typeID #2, #5, and #23 for example.
As i understand, the Map view could have many markers ( which is logic). so i think a join table would be the best solution. A table for example called MapMarkers that has the following structure :
MapMarkers
| id | MapID | MarkersID | ?? | ( you can add other infos for example if you want to store personnalized maps for each client you can add userID)
You should use a third table which represents a relation between two tables:
mapView ---- < mapView-markerType > ---- markerType
mapView-markerType would have the attributes: | id | mapID | typeID |
(you should get a shorter name than mapView-markerType, obviously)
EDIT
Considering the changes you made on the post, you would get:
mapView_markerType
id* | mapId | typeId
--------|----------|----------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 3
EDIT2
So, to further explain what I meant on the comment below:
map view
+------+---------------------+----------+
|mapID | name | typeComb |
+------+---------------------+----------+
|1 | Schoool & Shops | {1,2} |
|2 | Hospitals & Schools | {1,3} |
+------+---------------------+----------+

Categories