How to deal with user options and mysql database - mysql

I'm writing a PHP program. Each content has some options which stores users preferences. For example:
Where the content should be shown in the template?
In which categories or pages, the content should be loaded?
Now, I store these data in a single field named options as JSON. the final result is something like:
{
"locales":["en"],
"themes":{
"default":{
"width":"0",
"height":"0",
"top":"0",
"right":"0",
"bottom":"0",
"left":"0"
}
},
"pages":["aboutus\/"],
"categories":["all"],
"homepage":"false"
}
I have no problem to select data and filter rows using mysql regexp statement. But I have 3 other questions:
How to update a JSON field value in a single update statement?
Does it make sense to do such a trick at all (I mean using JSON)?
What other solutions do you recommend to store options, while there a lots of property to be stored?

AFAIK, there is no absolute way to do that in none-NoSQL database like MySQL. However, not exactly for JSON, you can see how FriendFeed uses MySQL to store schema-less data and it may give you some ideas.
UPDATE:
MySQL 5.7.8 and newer versions are now supporting JSON data type. There are some tutorials to help.

Related

Saving comma delimited data from a web application

I am using ColdFusion 10, but this question can be true for any web-application. I am trying to save a set of checkboxes with the same name. When they are posted, the form variable stores them as a comma separated list of IDs. Normally I would receive it as a varchar parameter in a storedprocedure and will parse them in t-sql to get to the individual values and inserting them to a table. I have been using this technique for quite some time.
I just want to check with you guys if there is any newer way of doing this. Basically what I am asking is how do you save a bunch of html checkboxes into a database table elegantly without using some kind of grunt code, like parsing.
I might use listToArray( form.fieldname ) to turn the list into an array, then loop over the array to do inserts.
Probably this will work. First convert to xml and then use xml to insert into table:http://beyondrelational.com/modules/2/blogs/28/posts/10300/xquery-lab-19-how-to-parse-a-delimited-string.aspx

MySQL increment value in a text field

Say I have a text field with JSON data like this:
{
"id": {
"name": "value",
"votes": 0
}
}
Is there a way to write a query which would find id and then would increment votes value?
I know i could just retrieve the JSON data update what I need and reinsert updated version, but i wonder is there a way to do this without running two queries?
UPDATE `sometable`
SET `somefield` = JSON_REPLACE(`somefield`, '$.id.votes', JSON_EXTRACT(`somefield` , '$.id.votes')+1)
WHERE ...
Edit
As of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON documents.
JSON_EXTRACT will allow you to access a particular JSON element in a JSON field, while JSON_REPLACE will allow you to update it.
To specify the JSON element you wish to access, use a string with the format
'$.[top element].[sub element].[...]'
So in your case, to access id.votes, use the string '$.id.votes'.
The SQL code above demonstrates putting all this together to increment the value of a JSON field by 1.
I think for a task like this you're stuck using a plain old SELECT followed by an UPDATE (after you parse the JSON, increment the value you want, and then serialize the JSON back).
You should wrap these operations in a single transaction, and if you're using InnoDB then you might also consider using SELECT ... FOR UPDATE : http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
This is sort of a tangent, but I thought I'd also mention that this is the type of operation that a NoSQL database like MongoDB is quite good at.

What is DC2Type array datatype in mysql

I have been working with Symfony2 and doctrine2 recently and have realized a peculiar datatype called DC2Type:array that certain Symfony2 Roles get saved as. To me it just looks like a serialized PHP array where a signifies the total number of elements, i is the array index.
The value looks like this:
a:15:{i:0;s:32:"ROLE_SONATA_USER_ADMIN_USER_EDIT";i:1;s:32:"ROLE_SONATA_USER_ADMIN_USER_LIST";i:2;s:34:"ROLE_SONATA_USER_ADMIN_USER_CREATE";i:3;s:32:"ROLE_SONATA_USER_ADMIN_USER_VIEW";i:4;s:34:"ROLE_SONATA_USER_ADMIN_USER_DELETE";i:5;s:36:"ROLE_SONATA_USER_ADMIN_USER_OPERATOR";i:6;s:34:"ROLE_SONATA_USER_ADMIN_USER_MASTER";i:7;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_EDIT";i:8;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_LIST";i:9;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_CREATE";i:10;s:33:"ROLE_SONATA_USER_ADMIN_GROUP_VIEW";i:11;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_DELETE";i:12;s:37:"ROLE_SONATA_USER_ADMIN_GROUP_OPERATOR";i:13;s:35:"ROLE_SONATA_USER_ADMIN_GROUP_MASTER";i:14;s:10:"ROLE_ADMIN";}
I want to know what this datatype is?
And what do the following identifier signifies:
s:
I have searched the internet but haven't got any useful data.
I also bumped upon this cookbook entry - http://readthedocs.org/docs/doctrine-orm/en/2.0.x/cookbook/mysql-enums.html but didn't figure out the origin.
This is not a data type. You might have noticed that the column type is LONGTEXT. DC2Type:array is a comment of the field.
Doctrine uses the field's comment as column's metadata storage place. Since Mysql does not allow you to store an array, Doctrine use DC2Type:array as comment in order to know how to unserialize the content.
Take a look at the link below.
https://github.com/doctrine/dbal/issues/1614
From the link you mentioned, you can see that the comment DC2Type:enumvisibility indicates that the content of the field is a flag, indicating that the record is visible or not. It is not a new data type at all. It should be considered an helper strategy in the database level. For Doctrine, it's a custom data type.
This is simply a string. Its format is a serialized PHP array. The s: refers to the size or length of each item value in the array.
e.g. s:32:"ROLE_SONATA_USER_ADMIN_USER_EDIT"
If you count the characters in the ROLE string, there are 32.
Hope this helps.

Mysql INSTR like operation in mongodb

Completely new to mongo here.
I have following fields in on of my mysql tables:
id (BIGINT), text (LONGTEXT) #this would contain a long description
I am hoping to change my project from Mysql to MongoDB, but before I do that there is very crucial query that needs to be resolved.
My current query looks for various terms in the description and returns all ids, e.g.
select id from <table> where instr(<table>.text, 'value') or instr(<table>.text, 'value2)
Is it possible for this to be recreated in Mongo? if so how? right now using either the $or or $in seems that I need to have those specific values in some kind of an array in my document.
MongoDB does not natively support full text search at the moment.
You could use regular expressions but it would be slow (due to not using indexes unless they are rooted).
Query would be like:
db.collection.find({ $or: [{description: /value1/}, {description: /value2/}] })
You could do some preprocessing to insert each word into a searchable array of keywords but if the text is really long you probably don't want to go this route.

Format list of urls in mysql

I have a list of a million or urls in an mysql table.
I need to cleanse the data (extract domains) so I can be confident about DISTINCT type queries.
Data is in several different types: -
www.domain.tld
domain.tld
http://domain.tld
https://vhost.domain.tld
domain.tld/
There are invalid domains and empty data.
Ideally I'd like to do something along the lines of : -
UPDATE table1 SET domain = website REGEXP '^(https?://)?[a-zA-Z0-9\\\\.\\\\-]+(/|$|\\\\?)'
domain being a new empty field, website being the original url.
You can't use regex like that in MySQL as is, but apparently you can some some UDFs that implement it. See:
How to do a regular expression replace in MySQL?
https://launchpad.net/mysql-udf-regexp
http://www.mysqludf.org/lib_mysqludf_preg/