I am creating an application with a click to call button on an html page.
There will be one person manning the phone. I want this person to be able to set a variable with a boolean value on my server: 1 is available, 0 is unavailable.
I could create a single field SQL table but this feels like overkill, or I could read and write to a text file containing just one character.
What is the most correct way to store a single value?
I know it seems like overkill to use a small database table for this.
If your application already uses a database, this is by far the best way to proceed. Your database technology has all kinds of support for storing data so it doesn't get lost. But, don't stand up a database and organize your application to use it just for this one data point; a file will be easier in that case.
(WordPress does something similar; it uses a table called wp_options containing a lot of one-off settings values.)
I suggest your table contain two columns (or maybe more), agent_id and available. Then, if you happen to add another person taking telephone calls, your app will be ready to handle that growth. Your current person can have agent_id = 0.
If you have a DB set up, I'd use it.
That's what DB's are for, persisting changeable data.. otherwise you are basically writing your own separate DB system for the sake of one setting, which would be uberkill in my eyes!
There is value in consistency and flexibility.. what if I suddenly need to store an expected return time? How do I do this in a text-file, how do I differentiate the column? How do I manipulate the data? MySQL already answers all these questions for you.
As a team member, I'd expect most of my dev colleagues (and new hires) to know how to use MySQL.. I wouldn't want them to have to work with, extend or debug a separate bespoke file persistence system that I had tacked on.
If you are worried about having lots of one row tables dotted about, you could use a single table for miscellaneous singular config variables which need updating regularly.
We have a table like this:
Table: `setting`
Columns: `key_string` VARCHAR, `value` VARCHAR
And could store your variable as
['key_string' => 'telephone_service_available', 'value' => '1']
In this specific case a simple file check (Exist a file or not) is probably the most simple way you can do here. And it also has the benefit to easily check if the file exist or not, you don't have to read file contents.
But if you need just one more information, you have to go a complete other way.
Depends on what you try to do afterwards with the information.
If you use it within a web-application store it in the session.
Or try a flatfile-database like SQLite (no active DBMS needed). Its easy and you can extend it very easy.
Or just a bipolar information with creating a file. If the file is not there is is off.
Related
Here is what my table looks like: http://jsfiddle.net/Draven/kGtx7/14/
Each header cell is clickable to be able to sort by that field and by ASC / DESC.
I want to be able to store that sorting option somewhere, so it get's remembered, but am not sure the best way to do that.
Here are the options I was thinking...
Making sort_field and sort_order fields in the users table
Making a new table that has their userid along with sort_field, and sort_order fields
Or Cookies, but I assume this is the worst option
I don't think we are clear on what you want, but I think you are wanting something like this:
Step 1: Run a query than will populate the sorting values into 2 session variables.
Step 2: Do something like this code.
$sortHeadClicked = $_SESSION['headClicked']
$sortReturnDirection = $_SESSION['returnDirection']
//TODO: validate data before query
if ($result = $mysqli->query("SELECT * FROM table ORDER BY $sortHeadClicked $sortReturnDirection))
{
//TODO: Get results
}
Step 3: Smile like your awesome
Alternatively, you could use some sort of sub select query.
NOTE: This is the simplistic logic so they won't be remember with this example. However, you can put the gets into session variables if you only want them to be remember temporarily
However, if you want these remembered permanently, you need two columns in your user's table where you would either puts them into sessions or use a subselect query
This is left up to interpretation, but each case would have its own uses.
1) Adding two fields to your users table will make the calls to retrieve these values easier but it is a much uglier approach to the problem than..
..2) Relational databases are built to be used as such. I'm not sure in terms of performance, but I do know that using the power of relational databases can make your db easier to navigate and understand/manipulate. While you may need some more complex calls (ie joins and whatnot), I believe the tradeoff is worth it.
and 3) Cookies are a very meh solution. They could be used in temporary cases, but if you are trying to save info for later, cookies can easily be deleted or not even enabled, at which point your site can suffer drastically.
Actually, using a cookie to store the user session id and then keeping session data in a database, flat file, or memcached is pretty common way to solve this. It would help to set up a reusable mechanism for this, like registry of sorts, that you can retrieve per user values at will. This only works if you have a user login of course. Otherwise there is no point in storing that data, as the users identity will be lost once they end the session (close the browser window). Most web apps will use cookies to identify you. If you delete that cookie, it forgets you and you are logged out.
Your first solution will suffer if you ever want to add another per user "preference" as you'd need to modify the underlying table.
Have a look at Zend Session for ideas if you are using PHP. If not the concepts still apply.
To save the sorting order to their profile, make the table inside a form and have the sortable field names be inputs. When they click one of the field names (sort by Location, for example), have the form's action run a PHP snip that updates a field in their profile on the database.
Alternately, if able to use ajax, you could simply add the database updating to an ajax call and skip the form.
I'm afraid that depends on your needs. How I see this problem:
good if you must share this settings between browsers, PCs, in
case if user delete cookies in browser. But it is not flexible - if
you will need to add another table, you will also add two additional
fields
the same as 1 in term of how it is shared between computers, browsers etc, but it is more flexible. You may add a column with table name easily.
If this setting is not so important and you may allow to loose setting in some cases. This solution is simplest, but it may not work for you
I'm working on some reusable code, basically. My idea is that I'd like to create an array based on a row in a database, where each column is the array's keys. The program then modifies the array, adding new keys if they weren't already in the database, and at the end of the program, the new array data is put back into the database, adding any new columns if they didn't exist first. Thus when making a new program with this reusable code, you don't have to mess with creating all the database columns.
I'm just looking for it to be an array, not some complex object. Kinda like the same way you would use $_SESSION or such. The database wouldn't change frequently, I'm only suggesting that the tables are created when the new program first runs, then don't change (so long as the programmer knows what he's doing). The array would be used securely; you wouldn't put user input into a $_SESSION key, would you?
So, a few questions.
Firstly, is this even a good idea?
Second, are there any similar stand-alone solutions already available which I can use or reference?
Finally, is there anything I should know about how to go about doing it if I need to from scratch?
Thank you a lot for any opinions or knowledge on this technique.
Well, if the programmer knows what columns he is going to use ahead of time, then he should just create the table. If the programmer doesn't know what the fields are called (they're determined by external forces like users, web service calls, etc), then you are opening yourself up for a major world of hurt as you have basically just passed all validation of data integrity to an outside source.
Outside sources are completely beyond your control and can do such lovely things as send bad data, especially if they happen to be users, or things operated by users, or things built by humans, or... well... anything else..
The rest of what you're talking about (select from a DB, modify returned value, save result) can be accomplished with things called Object-Relational-Maps. I can think of two good, standalone ORM systems in PHP: Doctrine and Propel.
Database structures shouldn't change frequently, which is what it sounds like your solution is intended to do. Usually creating any given table is just a single query once, with the occasional 'alter' as business needs change over time. Allowing for random mutability at the drop of a hat sounds like it'd be a nightmare to support.
Even if you did make it easy to add/alter/remove tables like this, there's still all the associated overhead of actually USING the new fields, removing deleted fields from existing code, yada yada yada.
I agree with others that traditional database tables shouldn't change like that. I'd suggest that you'd take a look at document databases like MongoDB, you can save array to the database as it is and you don't need to worry about the changing structure.
I am working on a web based application using Zend framework.
I am looking for a way to keep history of updates made to a bunch of columns.
Use-case:
User can add an item with 5 properties. The user is allowed to update the 5 properties. I need to track all the updates he makes to those 5 properties.
On way I thought of was adding a new table named log which stores the old value, new value, column name, itemID and timestamp.
What is the best way to do this? Are there any existing methods/options/examples ?
Thanks,
What you're probably looking for is an audit log. You can create one using Triggers on your MySQL database.
An example of how to do this is here: http://ronaldbradford.com/blog/auditing-your-mysql-data-2008-07-15/
In your comment below you added that the database is not 'fixed'. In that case, you'd have to replicate any alters to the table so that they are applied to the audit table in such a way that any newly added columns are added to the log as well.
You can consider logging this in your application (as your tags chosen for this question seem to suggestion) - but keep in mind that this means there can be situations where your log does not provide the complete answer. Triggers, stored procedures and any manual interventions in the database will not be logged... so be careful if you choose to go down that path.
Triggers are the most common way to do auditing and the only really reliable way to capture what was done whether done from the user interface or elsewhere. They do vary by database in how they would be written though. If you know the possible types of database backends you will support, you could write separate triggers for each.
If you must handle this without triggers, then your best bet is to have a process that writes to the audit table as well as makes the update change. It might be complex enough to warrant a stored proc called by the Zend framework rather than relying on the framework itself to do. (I'm not familair with Zend so I don't know if this is something that could be set up, I know a stored proc could handle this.)
Here is a better one..
See Pop On the Audit Trail
I just created a new table called it Comp_Hist_Log and then defined the old data in the
BEFORE UPDATE hook
$oldData = $array('fieldname1', 'fieldname2')
Then at the AFTER_UPDATE hook in my database gui hook file.. I added this code
sql("INSERT INTO Comp_Hist_Log (Com_Rec_Id, old_data, new_data, ChangedDate, ChangedBy)
VALUES('{$data['Record_Id']}', '{$oldData}', '{$messageData}', '{$data['LastUpdated']}', '{$memberInfo['username']}')", $eo);
return TRUE;
Hope it helps.. it does work.
To store multi language content, there is lots of content, should they be stored in the database or file? And what is the basic way to approach this, we have page content, reference tables, page title bars, metadata, etc. So will every table have additional columns for each language? So if there are 50 languages (number will keep growing as this is a woldwide social site, so eventual goal is to have as many languages as possible) then 50 extra columns per table? Or is there a better way?
There is a mixture of dynamic system and user content + static content.
Scalability and performance are important. Being developed in PHP and MySQL.
User will be able to change language on any page from the footer. Language can be either session based or preference based. Not sure what is a better route?
If you have a variable, essentially unknown today number of languages, than this definately should NOT be multiple columns in a record. Basically the search key on this table should be something like message id plus language id, or maybe screen id plus message id plus language id. Then you have a separate record for each language for each message.
If you try to cram all the languages into one record, your maintenance will become a nightmare. Every time you add another language to the app, you will have to go through every program to add "else if language=='Tagalog' then text=column62" or whatever. Make it part of the search key and then you're just reading "where messageId='Foobar' and language=current_language", and you pass the current language around. If you have a new language, nothing should have to change except adding the new language to the list of valid language codes some place.
So really the question is:
blah blah blah. Should I keep my data in flat files or a database?
Short answer is whichever you find easier to work with. Depending on how you structure it, the file based approach can be faster than the database approach. OTOH, get it wrong and performance impact will be huge. The database approach enforces more consistent structure from the start. So if you make it up as you go along, then the database approach will probably pay off in the long run.
eventual goal is to have as many languages as possible) then 50 extra columns per table?
No.
If you need to change your database schema (or the file structure) every time you add a new language (or new content) then your schema is wrong. If you don't understand how to model data properly then I'd strongly recommend the database approach for the reasons given.
You should also learn how to normalize your data - even if you ultimately choose to use a non-relational database for keeping the data in.
You may find this useful:
PHP UTF-8 cheatsheet
The article describes how to design the database for multi-lingual website and the php functions to be used.
Definitely start with a well defined model so your design doesn't care whether data comes from a file, db or even memCache or something like that. Probably best to do a single call per page to get an object that contains all the fields for that single page, rather than multiple calls. The you can just reference that single returned object to get each localised field. Behind the scenes you could then code the respository access and test. Personally I'd probably go the DB approach over a file - you don't have to worry about concurrent file access and it's probably easier to deploy changes - again you don't have to worry about files being locked by reads when you're deploying new files - just a db update.
See this link about php ioc, that might help you as that would allow you to abstract from your code what type of respository is used to hold the data. That way if you go one approach and later you want to change it - you won't have to do so much rework.
There's no reason you need to stick with one data source for all "content". There is dynamic content that will be regularly added to or updated, and then there is relatively static content that only rarely gets modified. Then there is peripheral content, like system messages and menu text, vs. primary content—what users are actually here to see. You will rarely need to search or index your peripheral content, whereas you probably do want to be able to run queries on your primary content.
Dynamic content and primary content should be placed in the database in most cases. Static peripheral content can be placed in the database or not. There's no point in putting it in the database if the site is being maintained by a professional web developer who will likely find it more convenient to just edit a .pot or .po file directly using command-line tools.
Search SO for the tags i18n and l10n for more info on implementing internationalization/localization. As for how to design a database schema, that is a subject deserving of its own question. I would search for questions on normalization as suggested by symcbean as well as look up some tutorials on database design.
I want to create a simple auditing system for my small CodeIgniter application. Such that it would take a snapshot of a table entry before the entry has been edited. One way I could think of would be to create a news_audit table, which would replicate all the columns in the news table. It would also create a new record for each change with the added column of date added. What are your views, and opinions of building such functionality into a PHP web application?
There are a few things to take into account before you decide which solution to use:
If your table is large (or could become large) your audit trail needs to be in a seperate table as you describe or performance will suffer.
If you need an audit that can't (potentially) be modified except to add new entries it needs to have INSERT permissions only for the application (and to be cast iron needs to be on a dedicated logging server...)
I would avoid creating audit records in the same table as it might be confusing to another developer (who might no realize they need to filter out the old ones without dates) and will clutter the table with audit rows, which will force the db to cache more disk blocks than it needs to (== performance cost). Also to index this properly might be a problem if your db does not index NULLS. Querying for the most recent version will involve a sub-query if you choose to time stamp them all.
The cleanest way to solve this, if your database supports it, is to create an UPDATE TRIGGER on your news table that copies the old values to a seperate audit table which needs only INSERT permissions). This way the logic is built into the database, and so your applications need not be concerned with it, they just UPDATE the data and the db takes care of keeping the change log. The body of the trigger will just be an INSERT statement, so if you haven't written one before it should not take long to do.
If I knew which db you are using I might be able to post an example...
What we do (and you would want to set up archiving beforehand depending on size and use), but we created an audit table that stores user information, time, and then the changes in XML with the table name.
If you are in SQL2005+ you can then easily search the XML for changes if needed.
We then added triggers to our table to catch what we wanted to audit (inserts, deletes, updates...)
Then with simple serialization we are able to restore and replicate changes.
What scale are we looking at here? On average, are entries going to be edited often or infrequently?
Depending on how many edits you expect for the average item, it might make more sense to store diff's of large blocks of data as opposed to a full copy of the data.
One way I like is to put it into the table itself. You would simply add a 'valid_until' column. When you "edit" a row, you simply make a copy of it and stamp the 'valid_until' field on the old row. The valid rows are the ones without 'valid_until' set. In short, you make it copy-on-write. Don't forget to make your primary keys a combination of the original primary key and the valid_until field. Also set up constraints or triggers to make sure that for each ID there can be only one row that does not have it's valid_until set.
This has upsides and downsides. The upside is less tables. The downside is far more rows in your tables. I would recommend this structure if you often need to access old data. By simply adding a simple WHERE to your queries you can query the state of a table at a previous date/time.
If you only need to access your old data occasionally then I would not recommend this though.
You can take this all the way to the extreme by building a Temportal database.
In small to medium size project I use the following set of rules:
All code is stored under Revision Control System (i.e. Subversion)
There is a directory for SQL patches in source code (i.e. patches/)
All files in this directory start with serial number followed by short description (i.e. 086_added_login_unique_constraint.sql)
All changes to DB schema must be recorded as separate files. No file can be changed after it's checked in to version control system. All bugs must be fixed by issuing another patch. It is important to stick closely to this rule.
Small script remembers serial number of last executed patch in local environment and runs subsequent patches when needed.
This way you can guarantee, that you can recreate your DB schema easily without the need of importing whole data dump. Creating such patches is no brainer. Just run command in console/UI/web frontend and copy-paste it into patch if successful. Then just add it to repo and commit changes.
This approach scales reasonably well. Worked for PHP/PostgreSQL project consisting of 1300+ classes and 200+ tables/views.