Codeigniter 2.1 - multi language insert - php

I need to insert data into DB in two language, and I am having a bit of a dilemma (data needs to exist in both languages). Is it better to make user insert data in both language at once, or is it better for the user to first insert in one language and then to insert in the second one? And if the latter is better how is the most efficient way to do this? How can I present all articles that are not inserted in both language?
DB structure for the articles:
Common table for all article (same data):
**article -> id_article | image | date_created | category_id | subcategory_id**
Table where data is different:
article_info -> article_id | name | text | lang_id

If the data must exist in both languages - i.e., the application assumes that if an item exists in one language, than it must exist in the other - then you should design your application so that the user must add them both at once.
When you perform the database writes, you should also be using transactions. This will ensure that either all of your writes succeed, or none of them do. It prevents the database from being left in an indeterminate state with a record for one language but not the other.
Have a look at this CodeIgniter manual page on transactions to get an idea on how they work.
You can also use the insert_batch method in the database class to insert both records at once. I don't know how it works with all database drivers, but the mysqli driver will generate a single query when you use insert_batch, so the entire insert will succeed or the entire insert will fail, similar to what happens with transactions. That said, I would still wrap the call to insert_batch in a transaction block just to be a bit paranoid and future-proof.

Related

How to Use MySQL and MongoDb together

I am planning of using MongoDB for my comments function. But all the user's data is in MySQL. That means, I am trying to store comments in MongoDB and other fix information in MySQL. But when I started to think about retrieving comments from MongoDB, I came across the question that, how can I relate MongoDB data with MySQL.
For example,
user name, profile_url is stored in MySQL
comments are stored in MongoDB with user_id
So how can I retrieve data like
| name | profile_url | comments |
|-------|--------------|-----------------------|
| xyz | image.jpg | That was nice comment |
| abc | image.jpg | I agree |
Is it possible to do so? Or is there any other way?
and I am using Laravel 5 with jenssegers/laravel-mongodb package.
MongoDB and MySQL are completely separate applications. They have no way to communicate with each other except through your application. That means if a request needs data from both sources, it needs to query both separately.
But what you could do is keep redundant data in both databases. When you store a comment in MongoDB, also put the relevant user information into the Comment document. Such a duplication of information is a deadly sin in relational databases but is common practice in MongoDB. Until recently (3.2) MongoDB had no support for JOINs whatsoever, and even now it's still quite rudimentary. That means you should usually avoid storing the data you need to fulfill a request in more than one collection, even if that means that you have redundancies.
You can't retrieve the user and comments data in the same time. You have to:
get the user ID
query mongodb using the user ID as parameter and get the comments you need
If you need aggregate data for more users, you could consider to aggregate the queries:
get all the users' data from mysql
query mongodb asking all the comments of the specified users
merge users data with comments data in PHP
Finally: are you sure storing the comments in mongodb is the right solution in your case? Are you planning to have a so huge ammount of comments at the point that it will require to store them in an external DB ?
If you choose this way, you can consider to store the user data in mongodb too. But before doing this, plan carefully if it's the right choice for you (i.e. consider the queries you'll need to do, and check if the data, stored in this way, would be fit for you queries )

MySQLi subscribe list table

I have a table called users and a table called pages. Users of the system can subscribe to a page and receive updates about the page. My problem is that users and pages will be updated dynamically (ie. no manual intervention to the tables) and I don't want to keep adding another column everytime someone subscribes to the page.
How can I achieve updating both the users table and the pages table dynamically to reflect that they have subscribed to that page?
My idea would be to add an comma separated array of usernames into the pages table and update them as users subscribe/unsubscribe.
Just making it an official answer:
While the initial hunch may be to use comma separated values to represent the link between those 2 tables (or any other way of saving the data in one column like saving a json string), it is actually bad practice because it does not conform to the First Normal Form (and definitely not 2nd and 3rd).
First Normal Form - Wikipedia
First Normal Form says you should never store more than 1 value in 1 table cell.
The problem, in short, starts when you'll need to use that data, which will actually take you at least 2 actions - 1 is reading the data from the database and 2nd is to parse it in your languaging script. Imagine what happens when you need then to use that data to read some other data from the database - you are making more sql queries than you need and taking at least twice the time (+resources). It becomes even more complicated when you need to use JOIN queries or have other one-to-many data relationships.
The solution then is simple - you need to create a 3rd table that serves as an intermediate table.
You can call it users_pages or user2pages and that represents the 1 to many relationship between 1 user and many pages.
The structure of the table is as simple as:
users_pages
-----------
-- id // a unique id for the relationship, can be auto generated
-- user_id // the user id
-- page_id // the page id
-----------
This allows you to build a more robust application as well as run advanced queries and calculations without the need to parse the data in your script (i.e count amount of pages each user is subscribed to, or amount of users subscribed to 1 page).
Unsubscribing can be also much easier this way since you don't need to read the users or pages table at all. You simply delete the relation from the users_pages table.
Without it, you will need to (a) first read the users table (b) get the pages data comma separated (c) parse the data and remove the specific page from it (d) save the new data again to the database. That's 4 actions and 2 SQL queries...
I hope this helps!

Storing values in two MySQL tables

I have a scenario in which I am not sure about what to do.
I have a website where a user can update their status. I am allowing the use of hash tags so a possible user post might look like:
Went for a great hike today!! #hiking
Now, I intend to store the post in a table appropriately named "POSTS" which is structured like this:
post_id | user_id | text | date
Now, when a user submits the form which holds the post text I run a script to create an array to get all of the hash tag terms the user used and then store them in an array.
So then I can loop through that array and insert the tags into the aptly named "TAGS" table. Now the structure of this table is this:
tag_id | post_id | user_id | tag
The only problem with this is that I do not know the post_id of the post until after I insert the data into the "POSTS" table (post_id is the primary key and is auto increment).
Now, I was thinking I could just SELECT the last row of data from the "POSTS" table for that user (after I insert the post), and then in turn use the returned post_id for my query that inserts the tag data into the "TAGS" table. This seems like not the best way? My question is:
Is this the best solution or is there a better way to go about this scenario?
I am brand new to Stack Overflow, so don't please down vote me. Comment and tell me what I am doing wrong and I will learn and ask better questions.
Thanks
You can get last insterted ID very simply:
mysql_insert_id() if you don't use PDO or using function lastInsertId() if you do.
Have a new column in both tables - unique_id - which holds a string you generate in code before querying the database. That way you have an id to tie posts and tags together before submission. I use this method all the time for similar applications.
Only issue is uniqueness, but there a variety of ways to generate unique ids (I normally use a mixture of timestamps and hashing).
This sort of depends on which version of mysql you're using and how you want to organize your code.
Option 1. Do exactly what you've said. PHP would contain the code to manage the database and how data is stored into the database. The only drawback that I see in what you've outlined is if there's an issue with dealing with the hashtags, then possibly you would have a post that is inserted to the database, but the hash part did not successfully complete. For certain applications (like a bank account), this may not be acceptable and this is what database transactions are for.
Option 2. Another way to handle this would be to write a mysql stored procedure that does both the insert and handling the hash tags. The stored procedure could also wrap the whole thing in a transaction so that your database is consistent. Note that this requires a version of mysql that supports stored procedures. The bad side of doing this is that you would have to write in mysql, which is different from PHP.
Both mysql and PHP can handle this application logic/datastore logic. It is a matter of how you want to organize the code. I would prefer keeping the layers distinct. Even if you are to do this in PHP, at least have a separate class that deals with the database and not do anything else. When your code gets bigger, having a separate class or module or namespace that manages these types of code really makes them easier to change and to test.

Can I use MySQL temporary tables to store search results?

I have a search page written in PHP, and it needs to search in the MySQL database, and the result need to be sortable. This search page will be accessed by many users (>1000 at any time).
However, it is not feasible to sort the search result in MySQL, as it would be very slow.
I'm thinking of storing each search result into a temporary table (not MySQL temporary table), and the table name is stored inside another table for reference like this:
| id | table_name | timeout |
-----------------------------
| 1 | result_1 | 10000 |
| 2 | result_2 | 10000 |
Then I can use the temporary tables to sort any search results whenever needed without the need to reconstruct (with some modification) the query.
Each table will be dropped, according to the specified timeout.
Assuming I cannot modify the structure of existing tables that are used in the query, would this be a good solution or are there better ways? Please advice.
Thanks
There's no need to go to the trouble of storing the results in a persistent database when you just want to cache search results in memory. Do you need indexed access to relational data? If the answer is no, don't store it in a MySQL database.
I know that phpbb (an open source web forum which supports MySQL backends) uses a key-value store to back its search results. If the forum is configured to give you a link to the specific results page (with the search id hash in the URL's query string) then that link will be valid for awhile but eventually be flushed out of the cache, just like you want. It may be overkill to implement a full database abstraction layer if you're set on MySQL though. Anyway:
http://wiki.phpbb.com/Cache
You should just use memcached or something to store the results data, and you can easily retrieve the data and sort it in PHP. Also there are some PHP-specific cache frameworks that minimize the cost of loading and offloading data from the interpreter:
https://en.wikipedia.org/wiki/List_of_PHP_accelerators

PHP MySQL inserting data to multiple tables

I'm trying to make an experimental web application which minimises redundant data.
I have three example tables set up like so:
Table one
ID | created_at (unix timestamp) | updated_at (unix timestamp)
Table two
ID | Foreign Key to table one | Title
Table three (pages)
ID | Foreign Keys to both table one and two | Content | Metadata
The idea being that everything created in the application will have a creation/edit time.
Many (but not all) things will have a title (For example a page or a section for a page to go into).
Finally, some things will have attributes specific to themselves, eg content and metadata for a page.
I'm trying to work out the best way to enter data into multiple tables. I know I could do multiple insert queries from PHP, keep track of rows created in the current transaction and delete those rows should a later part of the transaction fail. However, if the PHP script dies completely, it may stop before all of the deletions can be completed.
Does MySQL have any inbuilt logic which would allow the insert query to be split up? Would a trigger be able to handle this type of transaction or is it beyond its capabilities?
Any advice, thoughts or ideas would be greatly appreciated.
Thanks!
A solution would be to use Transactions, which allow to get "all or nothing" behaviour.
The idea is the following :
you start a transaction
you do your inserts/updates
if everything is OK, you commit the transaction ; which will save everything you did during this transaction
if not, you rollback the transaction ; and everything you did in it will be cancelled.
if you don't commit and disconnected (if your PHP script dies, for instance), nothing will be commited, and what you did during the un-commited transaction will automatically be rolled-back.
For more informations, you can take a look at 12.4.1. START TRANSACTION, COMMIT, and ROLLBACK Syntax, for MySQL.
Note that transactions are only available for some DB engines :
MyISAM doesn't support transactions
InnoDB does (it also supports foreign keys, for instance -- it's far more advanced that MyISAM).
For multiple inserts you can create a procedure and on PHP you call the procedure.

Categories