views:

73

answers:

3

I am trying to store a json encoded array into a MySQL field. The stored array is in the form:

['value1', 'value2', 'value3']

Then I try and run a query like:

SELECT * FROM mytable WHERE arrayfield

it returns no results. The arrayfield is either blank or contains an array, so I am trying to get the records that only contain an array in that field.

+2  A: 

Try

SELECT * FROM mytable WHERE arrayfield != ''

Does that produce any results?

Josh
+1  A: 

Did you properly escaped your data when inserting/updating with your SQL query (see mysql_real_escape_string and sprintf)? Are magic quotes OFF?

As Machine points out this is rather a bad design since relational databases aren't meant for that kind of stuff...

Also test these queries:

SELECT * FROM mytable WHERE arrayfield != ''

or

SELECT * FROM mytable WHERE arrayfield IS NOT NULL

do they both return empty results? If so, check that your INSERT/UPDATE query are working...

AlexV
+4  A: 

You shouldn't store arrays, or any kind of object, in a relational database. A relational database, to be in first normal form, should consist only of fields with basic datatypes. That is INT, CHAR, VARCHAR, DECIMAL etc. Additionally, it should contain no repeating groups, and the columns should have no intrinsic ordering. Arrays, by their very definition, violates this. If you feel the need to store other values, you have misunderstood the concept of a relational database.

If you want to store objects, such as arrays etc, then you should try some database system that is created for such use, i.e. Object Databases

The best way to store the array is to make an additional table for the array, and put each value of the array in its own row, then store some kind of array identifier in the parent table.

Example:

CREATE TABLE People (
  ssn INT,
  first_name VARCHAR(15) NOT NULL,
  last_name VARCHAR(20) NOT NULL,
  PRIMARY KEY (ssn)
);

CREATE TABLE Emails (
  belongs_to INT,
  email VARCHAR(128),
  PRIMARY KEY (belongs_to, email),
  UNIQUE(email),
  CONSTRAINT fk_belongs_to_ssn FOREIGN KEY (belongs_to) REFERENCES People (ssn)
);

In this schema, every person can have multiple emails. Each email belongs to a person in the People table. A set of emails can be found for a person by joining People with Emails on ssn = belongs_to. A single email can easily be found by searching the email-column for a particular value and/or pattern.

PatrikAkerstrand
But isn't that the point of serializing the array? Which I am doing with json_encode?
ssergei
Imagine you want to find every recods that have an array who contains 'value2' in it. How can you do that easily with a single SQL query? It's one reason why storing objects in relational databases is "bad".
AlexV
`SELECT * FROM mytable WHERE arrayfield ILIKE '%value2%';` You're right though - thats not a good way to go about things.
thetaiko
@thetaiko Which will also fetch records value234, value2xplamgoganjma, oamfvalue2 etc.
PatrikAkerstrand
@ssergei json_encoding the data to make it masquerade as a string does nothing to change the fact that the column still has intrinsic ordering.
PatrikAkerstrand
@machine - you'll notice I also commented that its not the right way to go about things. However, it is an easy single query that finds 'value2'
thetaiko
@thetaiko - Sure, but the problem is that it finds any row that contains the string value2, not necessarily the value value2
PatrikAkerstrand