Database Design - Entity–attribute–value Model Query - mysql

I have finally stumbled across a problem that I can't already find the answer to on SO...
I am working on a database that will store recorded sampled data recorded over time. Originally, the client had built a table that was very specific to the data that they were currently recording, however, they would are concerned that as they expand, the collected data may begin to vary, and more, or at least different, columns may be required.
Current model:
+------------------+ +------------------+
| FACILITIES | | DATA_RECORD |
+------------------+ +------------------+
| ID | | ID |
| NAME | | FACILITY_ID |
| DESC | | TIMESTAMP |
| etc. | | TEMP_WATER |
+------------------+ | TEMP_AIR |
| pH_WATER |
| etc... |
+------------------+
I think the database should be designed as follows:
+------------------+ +------------------+ +------------------+
| FACILITIES | | DATA_RECORD | | COLUMNS |
+------------------+ +------------------+ +------------------+
| ID | | ID | | ID |
| NAME | | FACILITY_ID | | NAME |
| DESC | | details etc.. | | DESC |
| etc. | +------------------+ | UNITS, etc... |
+------------------+ +------------------+
+------------------+
| DATA_POINT |
+------------------+
| ID |
| DATA_RECORD_ID |
| COLUMN_ID |
| VALUE |
+------------------+
My questions are:
Is this the best way to design the database, or is there a better way that I am not familiar with.
How do I form the query statement to return each data record with each of its associated columns?
Is there a generally accepted good data-type to use as DATA_POINT.VALUE? e.g. float, decimal...?
Thank you so much for your help.
Sincerely,
Nate K.

Looking at your requirements, I think you'd be leaning more towards the Entity-attribute-value type of design, which in general is tough to query (although it is fairly simple to set up) and not very scalable.
You can search for EAV models on this site or on google to see discussions about this.
http://www.simple-talk.com/content/print.aspx?article=843
Entity Attribute Value Database vs. strict Relational Model Ecommerce
http://tkyte.blogspot.com/2009/01/this-should-be-fun-to-watch.html
For your case, can you post the different types of Facilities and datapoints that you'd need to collect? May be you can use types and subtypes to model this?

Related

MySQL UPDATE | How to update filepath URI that saved in database

I have a table album that contains about 1000 rows. I want to update all rows.
Table album have a column named path. See full table structure below.
+---------------------------------------------------------------------------------------------+
| id | name | path |
+---------------------------------------------------------------------------------------------+
| 1 | Believe | Believe |
+---------+-----------+-----------------------------------------------------------------------+
| 2 | A Promise | A Promise |
+---------+----------+------------------------------------------------------------------------+
| 3 | Forever | Forever |
+---------------------------------------------------------------------------------------------+
I want to update path here. Want to add album in path for SEO friendly URLs. table should look like this for that goal.
+--------------------------------------------------------------------------------------------------+
| id | name | path |
+--------------------------------------------------------------------------------------------------+
| 1 | Believe | Believe |
+---------+-----------+----------------------------------------------------------------------------+
| 2 | A Promise | A Promise|
+---------+----------+-----------------------------------------------------------------------------+
| 3 | Forever | Forever |
+--------------------------------------------------------------------------------------------------+
I can't figure out how to use LIKE here, what to insert between % %. Please help me. Thanks in advance.

Database schema for simple poll

I am going to create simple poll for my shop customers. Poll will be display during order process so ID of customer is sufficient protection, poll will be display at first order only.
In poll will be only one question few one choice answers. One of these answers will be "custom". Customer will be able to type own answer.
I have problem how to build my database schema. I prepared this:
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | NO | | | |
| customer | int(11) | NO | | | |
| answer | varchar(160) | NO | | | |
+----------+--------------+------+-----+---------+-------+
In answer column will be ID of selected answer or custom text which customer typed to text input.
What do you think about that solution?

Design of simple store DB

I need to create DB of store that has books, CDs and DVDs. There are 3 categories of books: programming, cookery and e.g. spirituality. All goods have name, price, bar code. Books have pages and parametrs specialized for each category of books -- language for programming books, main ingredient for cook books, and age limit for spirituality. CDs and DVDs are devided to misic, video and Software. So, when I design DB I have a problem in connecting table: I have to take data from three different tables for one field.
+-----------+
| Tables |
+-----------+
|Categories |
|Languages |
|Main_Ingred|
|Age_Limits |
|Books |
+-----------+
+--------------+
| Books |
+--------------+
|id |
|category_id |
|price |
|bar_code |
|pages |
|special_param.| // Here I have to use data from 3 different tables
+--------------+
I think it is not right decision. Could you help me?
And I'll have the same issue for design of common table of goods.
Try this:
Books, CD-s, DVD-s and whatsoever go to table products (i added the fields all of your products have)
+--------------+
| Products |
+--------------+
|id |
|name |
|price |
|bar_code |
+--------------+
then there is a table categories
+--------------+
| Categories |
+--------------+
|id |
|name |
+--------------+
then connect the two tables (i have made many to many just in case one product goes to more categories)
+--------------------+
| Product2Categories |
+--------------------+
|id |
|product_id |
|category_id |
+--------------------+
last is the table for those special attributes like language, age limit, ingredients etc.
+--------------+
| Attributes |
+--------------+
|id |
|name |
+--------------+
then you need to connect the Product with the special attribute and assign the correct value:
+---------------------+
| Attributes2Products |
+---------------------+
|id |
|product_id |
|attribute_id |
|value |// varchar(255)
+---------------------+
Now this is ok but its not ideal because different attributes have different type of values, like language for programing books is a varchar, or age limit for spirituality is an integer, in the example above all the special attribute values are varchars.
If u want to optimize the database above you would need to edit the Attributes table:
+--------------+
| Attributes |
+--------------+
|id |
|name |
|type | //type of data it recives
+--------------+
and then create as many of Attributes2Products tables as there are datatypes you intend to use like if attribute is an integer type u save the special attribute value in table:
+---------------------+
| IntegerAtt2Products |
+---------------------+
|id |
|product_id |
|attribute_id |
|value |// int(11)
+---------------------+
or if attribute is a string type
+---------------------+
| VarcharAtt2Products |
+---------------------+
|id |
|product_id |
|attribute_id |
|value |// varchar(255)
+---------------------+
and so on.
Hope this helps.

mysql - select distinct mutually exclusive (based on another column's value) rows

First off, I would like to say that if after reading the question, anyone has a suggestion on a more informative title for this question, please tell me, as I think mine is somewhat lacking, now, on to business...
Given this table structure:
+---------+-------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account | varchar(20) | YES | UNI | NULL | |
| domain | varchar(100) | YES | | NULL | |
| status | enum('FAILED','PENDING','COMPLETE') | YES | | NULL | |
+---------+-------------------------------------+------+-----+---------+----------------+
And this data:
+----+---------+------------------+----------+
| id | account | domain | status |
+----+---------+------------------+----------+
| 1 | jim | somedomain.com | COMPLETE |
| 2 | bob | somedomain.com | COMPLETE |
| 3 | joe | somedomain.com | COMPLETE |
| 4 | frank | otherdomain.com | COMPLETE |
| 5 | betty | otherdomain.com | PENDING |
| 6 | shirley | otherdomain.com | FAILED |
| 7 | tom | thirddomain.com | FAILED |
| 8 | lou | fourthdomain.com | COMPLETE |
+----+---------+------------------+----------+
I would like to select all domains which have a 'COMPLETE' status for all accounts (rows).
Any domains which have a row containing any value other then 'COMPLETE' for the status must not be returned.
So in the above example, My expected result would be:
+------------------+
| domain |
+------------------+
| somedomain.com |
| fourthdomain.com |
+------------------+
Obviously, I can achieve this by using a sub-query such as:
mysql> select distinct domain from test_table where status = 'complete' and domain not in (select distinct domain from test_table where status != 'complete');
+------------------+
| domain |
+------------------+
| somedomain.com |
| fourthdomain.com |
+------------------+
2 rows in set (0.00 sec)
This will work fine on our little mock-up test table, but in the real situation, the tables in question will be tens (or even hundreds) of thousands of rows, and I'm curious if there is some more efficient way to do this, as the sub-query is slow and intensive.
How about this:
select domain
from test_table
group by domain
having sum(case when status = 'COMPLETE'
then 0 else 1 end) = 0
I think this will work. Effectively just joins two basic queries together, then compares their count.
select
main.domain
from
your_table main
inner join
(
select
domain, count(id) as cnt
from
your_table
where
status = 'complete'
group by
domain
) complete
on complete.domain = main.domain
group by
main.domain
having
count(main.id) = complete.cnt
You should also ensure you have an index on domain as this relies on a join on that column.

Select followers and connections that they are not followers in MySQL

I have a complicated query to resolve and I don't know how to get the correct results. First of all, let me show you the tables I have:
+------------+
| users |
+------------+
| id |
| first_name |
| last_name |
+------------+
+--------------+
| clients |
+--------------+
| id |
| users_id |
| uid |
| access_token |
+--------------+
+---------------+
| users_follows |
+---------------+
| users_id |
| follow_id |
+---------------+
+-------------------+
| users_connections |
+-------------------+
| id |
| users_id |
| clients_id |
| uid |
| name |
+-------------------+
Our website uses Facebook Connect, so EACH user connected has a client UID (Facebook UID). For a functionality of the website I need a query that does the next: select all the the people you follow (users_id=ME) plus the users_connections but if a users_connection is also someone I follow do not include it on the final result. Finally, for this rows if it's a "following" I need users.first_name and users.last_name and if it's a connection NOT registered on our website I need users_connections.name.
I will have a lot of rows an probably people can have a lot of people who follow so a NOT IN and id's concatenated I think that it's not the best way to scale it.
Can anyone bring me some light?
Thank you in advance!