I am currently planning out how a table will look in MYSQL database. I want to do something like the below, where plant1 and plant2 would be the columns, and then each of those plants would have characteristics assigned to them as you see below.
Is it possible to display info this way in MYSQL?
Array (
[plant1] => Array (
[image_url] => http://www.example.com/image1.png
[botanical_name] => Foo
[common_name] => Bar
),
[plant2] => Array (
[image_url] => http://www.example.com/image2.png
[botanical_name] => Foo
[common_name] => Bar
)
Well, i don't suggest that, but you can insert php array to that field and then parse it in php when you are getting data from database. So the content of that field would be like that:
$plant1 = array('plant1' => array('image_url' => 'http://www.example.com/image1.png', 'botanical_name' => 'Foo', 'common_name' => 'Bar'));
$plant2 = array('plant2' => array('image_url' => 'http://www.example.com/image2.png', 'botanical_name' => 'Foo', 'common_name' => 'Bar'));
You can insert $plant1 $plant2 to your mysql fields and then print it like this to get wanted result:
print_r(array_merge($mysql_plant1, $mysql_plant2));
Function array_merge connects arrays together.
You can do it storing as a serialized value (http://www.php.net/manual/en/function.serialize.php) but it's not a good idea.
For that you will have to create another table to store the caracteristics of each plant like:
**plants**
id_plant
name
**plants_ccharacteristics**
id_plant_characteristic
fk_plant
name
value
In that way you can store it properly.
As an extra point, that structure you want to store looks quite good for use NoSQL databases like MongoDB.
Your table design is flawed. What you should have is Plant being a row, with each item in the array being a column in the plants table.
If you need Plants to be a column in another table, then assign the first column of the plants table to be a unique, auto-incrementing key and then put that key in the column of the other table. Eg:
**Garden_Plants**
gp_key
gp_garden_id
gp_plant_id <-- p_id from Plants_Table
**Plants_Table**
p_id
p_botanical_name
p_common_name
p_image_url
you would have a table called plants, this would have a related table called plantDetails that has a referencing ID from the plant in question.
this would give 1 plant, with multiple references
This doesn't seem optimised for querying the database, however if you have a specific reason for doing it this way please let us know..
A more optimised solution:
Have a table called Plants, with fields ID, image_url, botanical_name, common_name.
Store all plants in that table. ID is a unique Identifier for that plant, probably set with autonumber so cannot be duplicated
If you need to store some kind of relationship between 2 plants, have a table called plant_relationships with fields for something like plant_ID_1 and plant_ID_2
You can then query your full list of plants directly, or query the relationships table to find plants related to other plants
If you want multiple values in one mysql field, i would suggest to put your information in one string before storing it in the database. Each substring need to be separated by a character that will not be used in the substrings.
$value1 = aaa
$value2 = bbb
$value3 = ccc
$valueAll = aaa:bbb:ccc
When you get the data out of the DB, you will need to split the string with the : or the other character selected.
Related
I 1000+ have rows of SQL data that look like the followinng
umeta_id | user_id | meta_key | meta_value
433369 | 44 | all_contests | a:1:{s:12:"all_contests";a:2:{i:5011;a:1:{s:7:"entries";i:3;}i:8722;a:1:{s:7:"entries";i:3;}}}
433368 | 63 | all_contests | a:1:{s:12:"all_contests";a:2:{i:5032;a:1:{s:7:"entries";i:3;}i:8724;a:1:{s:7:"entries";i:3;}}}
When you unserialize one of those values you get an array like the following:
Array
(
[all_contests] => Array
(
[5011] => Array
(
[entries] => 3
)
[8722] => Array
(
[entries] => 3
)
)
)
I am trying to create a leaderboard out of all the users for a given contest id. The "all_contests" key holds an array keyed by the ids of all the contests the user signs up for. Inside that is the entries for the given contest.
The query needs to look at all the rows containing 'all_contests' keys and find the 10 highest entries values for a given contest id.
I'm not even sure that it is possible to reliably search inside of a piece of serialized data the way that I'm looking to.
No, it's impractical to search inside a piece of serialized data.
You can do it with enough meticulous usage of MySQL String Functions like INSTR(), SUBSTR(), FIELD(), and so on. But writing queries like that is time-consuming to develop the query, and it won't have good performance.
What you're doing is a variation on a common mistake: storing a comma-separated list in a column of one table.
This is avoiding creating the intersection table to represent a many-to-many relationship. In other words, you have two tables for users and contests, and you need a third table, in which each row represent's one user's participation in one contest.
See my answer to Is storing a delimited list in a database column really that bad?
The answer is about comma-separated lists, but it applies equally to serialized arrays like you're doing.
I have a movies table (has data from a legacy project) with the field genre which contains values serialized by PHP like:
a:3:{i:0;s:9:"Animation";i:1;s:9:"Adventure";i:2;s:5:"Drama";}
I'm working in a search page, & I need to find all unique genres of the current search result to be used as a filter in the page,
as an example, if the search result was these 2 movies:
The Dark Knight (action, crime, drama)
Black Knight (fantasy, adventure, comedy)
I want to know the combination of there genres, which will be:
['action', 'crime', 'drama', 'fantasy', 'adventure', 'comedy']
how to get the genres array? (I'm using Yii2).
You should unserialize your data
$data = 'a:3:{i:0;s:9:"Animation";i:1;s:9:"Adventure";i:2;s:5:"Drama";}';
$data = unserialize($data);
print_r($data);
and you will get
Array
(
[0] => Animation
[1] => Adventure
[2] => Drama
)
If you need to search the entire table for "Drama" to decide which shows/movies to display, you could always use wildcards in your search
select * from table where column like '%Drama%'
but of course make sure to take appropriate database precautions.
Suppose you have a serialize string that have various values in different position and you need to search from serialized field. You want particular key’s value using MySQL query. It is very easy with MySQL “%like%” statement but “%like%” fetches more matches which you do not require.
Search from serialized field: Suppose you have a following serialize string in database:
a:9:{s:2:"m1";s:4:"1217";s:2:"m2";s:8:"9986-961";s:2:"m3";s:19:"1988-03-07 00:00:00";s:2:"m4";s:0:"";s:2:"m5";s:0:"";s:2:"m6";s:0:"";s:2:"m7";s:3:"104";s:2:"m8";s:6:"150000";s :2:"m9";s:18:"Ok Then, Yes It Is";}
And you need the row in which the m9 value is ‘Yes It Is’.
So the sql will be like:
SELECT * FROM table WHERE field REGEXP '.*"array_key";s:[0-9]+:".array_value.".*'
test code
SELECT * FROM table WHERE field REGEXP '.*"m9";s:[0-9]+:".Ok Then, Yes It Is.".*'
Hello everyone and thank you for viewing this question.
Since someone asked what i am doing this for, here is the answer:
An artist asked me to make him a web app to store all his new concerts etc.. Now, when it comes to add the Instruments, artists etc, i could have 10 instruments, or maybe 100.. Everything is set into a form.. Some data is fixed like location, time etc, but this other fields are added dynamically using DOM..
I am building a system in which the user set up a form to be stored on a database like:
Name,Surname,field_1
//Lets say that this is the "fixed" part of the form
//But the user should be able to add 'n' other fields with no limit
//Therefore my problem is that i would end up with a row made of, lets say,
//4 colums
//And another one of, maybe, 100 columns
//
//Then i will need to access these rows, and row one should have 4 cols, row two 100..
//This can't be done in a "traditional" way since each row should have the
//same amount of cols
//
//I thought to create a new table for each submission
//but this doesn't really make that much sense to me..
//
//Storing all the possible fields in a single one and then
//access them through an array ? That would require too much, even since my fields
//should have the possibility to be edited..
//Each field is a mixture of variables then, like
//field1:a=12,field2:b=18.. too complex
Any help would be very appreciated
I would go the one field approach. You could have three columns, Name, Surname, and field_values. In the field_values column, store a PHP serialized string of an array representing what would otherwise be your columns. For example, running:
array(
['col1'] => 'val',
['col2'] => 'val1',
['col3'] => 'val2',
['col4'] => 'val3'
)
through serialize() would give you:
a:4:{s:4:"col1";s:3:"val";s:4:"col2";s:4:"val1";s:4:"col3";s:4:"val2";s:4:"col4";s:4:"val3";}
and you can take this value and run it back through unserialize() to restore your array and use it however you need to. Loading/saving data within this array is no more difficult than changing values in the array before serializing it and then saving it to the field_values column.
With this method you can have as many or few 'columns' as you need with no need for a ton of columns or tables.
In this case I would personally create a new table for each user, with new row inserted for ever new custom field. You must have a master table containing table names of each user table to access the data within later.
I have been struggling with the proper way to extract the data I need. I am using MySQL with PHP and will be putting the data into a list format. My only problem is with the actual query itself. Here is how the DB is setup:
I have a 'chars' table for characteristics with the columns 'id', 'descrip', and 'class'.
I have a 'animal' table with the columns 'animal_id', 'charlist', ...
In 'chars' id is an incremented int, 'descrip' and 'class' are text/strings.
'id' and 'descrip' are different for every row but 'class' will be the same sometimes having a value like 'habitat', 'size', 'diet', et cetra.
What I am going for is a list that will look like this:
Habitatundergroundarctic
Dietfishinsectsomnivore
Here is where I start to have trouble. On a 'Details' page I am showing all of the data specific to a certain animal (whichever is clicked) and to reference the 'characteristics' each animal has it's own 'charlist' value in the database. This value is a string of numbers that reference the 'chars' table, like '2,55,67,90,122'.
So I've pulled all my (specific) animal data to a php variable on the page that I want to supply with the information. Now I need to use the 'charlist' data from that animal to lookup and list the characteristics relative to the animal.
My queries are looking like this, and I know I'm waaay off:
SELECT * FROM 'chars' LEFT INNER JOIN 'animals' ON chars.id IN (animals.charlist) WHERE ...
I've tried a lot of different ways and this is where I get lost. My brain is telling me to join the tables, find the numbers that are in the charlist WHERE animal.animal_id = mysql_real_escape_string($animal_id) - and of course MySQL tells me I can't do it this way.
I know that for the titles of the lists I'll probably have to do this with a GROUP BY condition.
Any help on the query and query syntax would be great. I'm fairly new to MySQL and I'm very happy and eager to learn how to do this right.
Thanks for reading.
a IN (x) returns true if (and only if) a equals x.
If x is a string (even one delimited by commas), then the statement will only be true if a is equal to that same string. That is, 123 IN ('123,456,789') is false. Note that this is not the same as passing multiple arguments such as 123 IN (123, 456, 789).
In MySQL, one could instead use FIND_IN_SET(), which expects a string delimited by commas. However, storing delimited lists in database columns is a really bad idea. You should instead define a third, relationship, table in which you store foreign keys into both of your existing tables: (animal_id, characteristic_id):
CREATE TABLE animal_characteristics (
PRIMARY KEY (animal_id, characteristic_id),
FOREIGN KEY (animal_id) REFERENCES animal (animal_id),
FOREIGN KEY (characteristic_id) REFERENCES chars (id)
) SELECT animal.animal_id, chars.id AS characteristic_id
FROM animal JOIN chars ON FIND_IN_SET(chars.id, animal.charlist)
;
Then you can do:
SELECT *
FROM animals
JOIN animal_characteristics USING (animal_id)
JOIN chars ON chars.id = animal_characteristics.characteristic_id
WHERE ...
I've searched quite a bit for this but nothing has seem to to come up which is strange because I think it would be something that's something quite easy to implement. Basically I have a list of items which the user selects, what I want to do is update the values in the database according to the checkboxes selected basically the following scenarios:
The id assigned in the checkbox array is already in the DB and nothing needs to happen, or can be updated with the same value.
The id assigned in the checkbox array needs to be added to the database.
The id ISN't assigned in the checkbox array and therefor must be deleted from the DB.
has anyone got any code they worked with that does this?
EDIT:
the table is simple with two things being updated:
id_text and id_product
array coming from $_POST is:
Array ( [text] =>
Array ( [0] => 8 [1] => 1 [2] => 2 ) // the values that need to be inserted, updated, or deleted if they don't exist here.
[textValue] => ALL OF THEM
[id] => 33 // the 'id_product value'
[update] => update )
True, without any code or database squema is pretty hard to help, but if I understand correctly you can just:
Delete all values on DB.
Loop through the ids passed in POST or GET and insert them on DB.
Do an replace for every id passed. Replace behaves like insert i the entry does not exist and like update if it exists. I can not give you more details becuase I do not know your table structure
Delete all items that have a id that is not in your array. you can select those with "in":
...WHERE id_product NOT IN (1,3,5,8) AND......
you can easily generate this by using
$idCondition = 'id_product NOT IN (' . implode(',',$yourArrayName) . ')';
About REPLACE:
http://dev.mysql.com/doc/refman/5.1/de/replace.html
About IN:
http://www.webdevelopersnotes.com/tutorials/sql/tutorial_mysql_in_and_between.php3
EDIT: I just realized that some people might have objections on my deinition of REPLACE. What REPLACE actually does is deleting the row if it already exists and then do an INSERT.