Storing JSON in MySQL database? [duplicate] - php

This question already has answers here:
Storing Data in MySQL as JSON
(16 answers)
Closed 9 years ago.
Is it acceptable to store JSON data in a MySQL table row? I need to store arrays in a mysql database. The problem is, i don't know how many columns i will need for each user. So I thought to store JSON in one row named array for exemple. Is this the best way?
Edit:
Also, I am using text as table column type.

Yes, it's a very good idea to use mysql as a key-value store, in fact facebook does for some uses.
CREATE TABLE `json` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` blob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The above table-structure will get you far. It's very easy to shard or cluster.
Edit: The point here is to use PHP, Ruby etc to handle the json/data. You do SELECT ..., do your edits, then INSERT ... ON DUPLICATE KEY UPDATE ....

Storing more than one piece of data in a relational database field is generally wrong. It is possible to think of cases where it would be acceptable, but not for storing an entire user.
If a using a relational database structure is not sufficient you may want to look at a NoSQL database inestead of MySQL.

It's not a problem. mySQL can already handle most of the brackets and funky characters in their text field.

I think it is not. What about four months later you decide add a new attribute to your entity or remove some attributes from your entity? How will you parse your old json contents? If you dont know how many columns you will need in your table, you should think in a different way and maybe create a dynamic structure like using user_column table

Related

store unknown size array in mysql database

Hi I have in mysql database a datetime value (2015-01-01 12-54-32) which I use to know the date in which the library subscriber reserved a book it is easy to store one datetime value in database but the problem is i don't know how many books the subscriber will reserve from the library could be 1 or could be 5 , the question is how do i store it in database as array ?
The correct way to store this in a database is to use a junction table. Something like this:
create table BookReservations (
BookReservationId int auto_increment primary key,
SubscriberId int not null,
BookId int not null,
ReservationDate date not null,
constraint fk_bookreservations_subscriberid foreign key (SubscriberId) references Subscribers(SubscriberId),
constraint fk_bookreservations_bookid foreign key (BookId) references Books(BookId)
);
(Clearly, this just suggests names for entities and columns not mentioned in the question.)
Note that this table defines the foreign key relationships among the tables as well as storing the data. This allows the database to ensure relational integrity. MySQL does not (currently) allow such definitions for string or JSON objects.
If you really want to store multiple books in one field you can json_encode the array everytime you store it and then json_decode it again when you select it from the db.
But the better approach is to create a book_subscribe table where you can store as many as you like per subscriber.
Use serialize and unserialize to covert arrays and add it in your database column. Your question makes me think you have a database design issue. Take a look at one-to-many relationships (eg. one customer, several books)

How to get original insert statement from database [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get Insert Statement for existing row in MySQL
Lets say we have a table called users:
CREATE TABLE IF NOT EXISTS users(
UID int(11) PRIMARY KEY NOT NULL auto_increment,
fname varchar(100) default NULL,
lname varchar(100) default NULL,
username varchar(20) default NULL UNIQUE,
password blob
)ENGINE=InnoDB DEFAULT CHARSET=utf8
Lets assume there's a few rows filled up in the table.
I know there is a query that returns the creation of the table -> SHOW CREATE TABLE users
But I'm looking to recreate individual insert statements to save them in a log...I know this sounds weird, but I am making a custom CMS where everything is logged, and hopefully where updated/deleted rows could rollback at point in time...therefore I would need to recreate exact insertion query from table data (I have searched all over the web for an answer and can't find it...)
Is there a query that would return "automatically" the query that inserted that specific row by primary key?
I am looking for a query that would do this:
SHOW INSERT FROM users WHERE PRIMARY_KEY=2
Returns:
INSERT INTO users (UID,fname,lname,username,password) VALUES (2,'somename','somelastname','someusername','someAESencryptedPassword')
The reason I'm thinking such a query would exist/be possible is because when you backup a database with php myadmin (cpanel) and you open the file, you can actually view each insert to recreate the table with all rows a that point in time...
There is no such "command" (the data is stored, but not the actual SQL that inserted it), and it wouldn't make sense to do what you're asking. You do realize your "log" would be about 20 times larger (at least) than the actual table and data itself? And it's not going to able to retrieve the INSERT statement without a lot of work to track it down (see the comments below) anyway.
Study transactional SQL, make use of server logging and transactions, and back up the data regularly like you're supposed to and quit trying to reinvent the wheel. :-)
There is no such command to retrieve the original insert statement. However, you can always remake the insert statement based on the existent table structure and data.
The following link may help you, where this has already been asked:
Get Insert Statement for existing row in MySQL
Another possible option is using mysqldump with php to export the data as SQL statements.

Figuring out the most effective way for a custom database server (PHP)

I just came across the idea of writing a special database which will fit for exactly one purpose. I have looked into several other database-systems and came to the conclusion that I need a custom type. However my question is not about if it is a good idea, but how to implement this best.
The application itself is written in php and needs to write to a custom database system.
Because there can be simultaneous read/write operations I can forget the idea of implementing the database directly into my application. (correct me please if I'm wrong).
That means I have to create 2 scripts:
The database-server-script
The application.
This means that the application has to communicate with the server. My idea was using php in cli mode for the database-server. The question is, if this is effective, or if I should look into a programming language like c++ to develop the server application? The second question is then the communication. When using php in cli mode I thought about giving a serialized-array-query as a param. When using c++ should I still do it serialized? or maybe in json, or whatever?
I have to note that a database to search through can consist of several thousands of entries. So i dont know exactly if php is realy the right choice.
Secondly i have to note that queries arent strings which have to be parsed, but an array giving a key,value filter or dataset. The only maybe complexer thing the database server has to be able to is to compare strings like the MySQL version of LIKE '%VALUE%', which could be slow at several thousand entries.
Thanks for the Help.
writing a special database which will fit for exactly one purpose
I presume you mean a custom database management system,
I'm having a lot of trouble undertanding why this would ever be necessary.
Datasbes and Tables like usual databases have. But i dont have columns. Each entry can have its own columns, except for the id
That's not a very good reason for putting yourself (and your users) through a great deal of pain and effort.
i could use mysql id | serialized data... but then much fun searching over a specific parameter in a entry
So what's wrong with a fully polymorphic model implemented on top of a relational database:
CREATE TABLE relation (
id INTEGER NOT NULL auto_increment,
....
PRIMARY KEY (id)
);
CREATE TABLE col_string (
relation_id NOT NULL /* references relation.id */
name VARCHAR(20),
val_string VARCHAR(40),
PRIMARY KEY (relation_id, name)
);
CREATE TABLE col_integer (
relation_id NOT NULL /* references relation.id */
name VARCHAR(20),
val_integer INTEGER,
PRIMARY KEY (relation_id, name)
);
CREATE TABLE col_float (
relation_id NOT NULL /* references relation.id */
name VARCHAR(20),
val_float INTEGER,
PRIMARY KEY (relation_id, name)
);
... and tables for BLOBs, DATEs, etc
Or if scalability is not a big problem....
CREATE TABLE all_cols (
relation_id NOT NULL /* references relation.id */
name VARCHAR(20),
ctype ENUM('string','integer','float',...),
val_string VARCHAR(40),
val_integer INTEGER,
val_float INTEGER,
...
PRIMARY KEY (relation_id, name)
);
Yes, inserts and selecting 'rows' is more complicated than for a normal relational table - but a lot simpler than writing your own DBMS from scratch. And you can wrap most of the functionality in stored procedures. The method described would also map easily to a NoSQL db.

From javascript array to mysql

Im making a 100% javascript and canvas web application, no forms at all. I have a js array with data and I'm wondering how could be possible to pass it to a php script so it gets loaded into the database. Suggestions?
My thoughts are to keep it simple. If you are looking to store arrays based on value/pair, ie a flat file and no relationships between tables, then I would do the following:
Create a mysql database with one table, two rows:
CREATE TABLE `data` (
`data_id` INT(10) NULL,
`data_key` CHAR(50) NULL,
`data_value` TEXT NULL,
`datemodified` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`datecreated` DATETIME NULL,
PRIMARY KEY (`data_id`),
UNIQUE INDEX `data_key` (`data_key`)
)
COLLATE='latin1_swedish_ci'
ENGINE=MyISAM
ROW_FORMAT=DEFAULT
Anyway create a PHP script that will take a post of 2 variables, a key (a key), and value (this would be an object in javascript).
If you post a key, it should return the value (in the json format so javascript can interpret it into an object)
If you post a key and a value, the script will do an "Insert Ignore" and return the data_id. Run the value through json_encode() (as it will be if posted through javascript) and store it under the key.
You could also make an optional third way of accessing the data using the data_id value.
Just a thought... let us know how much php experience you have and if you need specific details on what functions to use
Security would also be a factor to consider. In this case, you might want to have javascript generate a unique session id, and then add this session_id to the table. So users can only access their own data. Not really sure how your app works at this stage though so sorry I can't suggest something more secure.
create a webservice in php that can connect to mysql db. Your js code would make calls to these webservices to save to db
You can send it as a JSON string to a PHP file using AJAX and then decode the JSON, inserting the data into the database. You should have the PHP file return something to make sure it's done.

PHP/MySQL - Storing array in database

I'm working on a PHP app which requires various settings to be stored in a database. The client often asks if certain things can be added or changed/removed, which has been causing problems with the table design. Basically, I had a lot of boolean fields which simply indicated if various settings were enabled for a particular record.
In order to avoid messing around with the table any more, I'm considering storing the data as a serialized array. I have read that this is considered bad practice, but I think this is a justified case for using such an approach.
Is there any real reason to avoid doing this?
Any advice appreciated.
Thanks.
The real reason is normalisation, and you will break the first normalform by doing it.
However, there are many cases in which a breach of the normal forms could be considered. How many fields are you dealing with and are they all booleans?
Storing an array serialized as a string in your database will have the following disadvantages (among others):
When you need to update your settings you must first extract the current settings from the database, unserialize the array, change the array, serialize the array and update the data in the table.
When searching, you will not be able to just ask the database whether a given user (or a set of users) has a given setting disabled or enabled, thus you won't have any chances of searching.
Instead, you should really consider the option of creating another table with the records you need as a one-to-many relation from your other table. Thus you won't have 30 empty fields, but instead you can just have a row for each option that deviates from the default (note that this option has some disadvantages aswell, for example if you change the default).
In sum: I think you should avoid serializing arrays and putting them into the databases, at least if you care just a tiny bit about the aforementioned disadvantages.
The proper way (which isn't always the best way)
CREATE TABLE mytable (
myid INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
mytitle VARCHAR(100) NOT NULL
);
CREATE TABLE myarrayelements (
myarrayid INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
myid INT UNSIGNED NOT NULL,
mykey VARCHAR(100) NOT NULL,
myval VARCHAR(100) NOT NULL,
INDEX(myid)
);
$myarray = array();
$res = mysql_query("SELECT mykey, myval FROM myarrayelements WHERE myid='$myid'");
while(list($k, $v) = mysql_fetch_array($res)) $myarray[$k] = $v;
Although sometimes it's more convenient to store a comma separated list.
One thing is that extensibility in limited. Database should not be mixed with programming environment. Also changing the values in database and debugging is much easier. The database and cgi can be interchanged to another database or cgi like perl.
One of the reasons to use a relational database is to help maintain data integrity. If you just have a serialized array dumped into a blob in a table there is no way for the database to do any checking that what you have in that blob makes any sense.
Any reason you can't store your settings in a configuration file on the server? For example, I save website or application settings in a config.php rather than a database.

Categories