I'm working on a web application that uses PHP for it's code,and MySQL for it's storage engine. When working on my data model, I realized that I have a small issue with the handling of 'default' data.
I designed the MySQL schema to include the defaults, which made sense at the time because I was mostly manipulating the data 'by hand' -- it's a year later that we got around to adding a Control Panel to let others change the data.
The issue becomes how to handle 'default' values that are needed for some objects. Technically, leaving things 'null' is also a default, but it wasn't one that particularly concerned me before now.
If I use the MySQL defaults, when I insert a new value I have to immediately turn around and query it to get the 'real' data out of the database. If, on the other hand, I set my defaults up in PHP, I start violating DRY by having defaults in two places. And if someone ever does a 'quick' fix and changes them in just one place, I could wind up with some pretty 'interesting' bugs to debug. At the same time, I can't remove the defaults from MySQL, because the really are part of the data schema, and need to be left in it.
I'm willing to bet I'm either overlooking something, or making an invalid assumption somewhere, but I don't know what it is. Anyone have any advice on how to handle this?
Edit:
For clarity, my PHP code might be something along the lines of:
$foo = new foo();
//Add in instance-specific data
$foo -> save;
Foo's save method would then run the query:
INSERT INTO FOO (bar1, bar2)
VALUES (:bar1, :bar2)
But that only inserts 2 of the (many) variables that Foo uses. All this does is set me up in the 'default' state. At the moment, I then have to run:
$foo= Foo::getFooWithId($foo->id); //I know I should use a DBA; this is legacy code
And $foo is then populated with the data that's been set up in the database. E. G. bar3 and bar4 have defaults that aren't set when first creating the object -- users can change them later if they want to (and probably will), but they aren't part of the 'default' object.
Should I move those defaults into PHP? Leave them in MySQL and pull out of it? Violate DRY by putting them in both places? Or am I missing a fourth, better option?
You didn't show us an example query, but I'll assume what's wrong.
If you write your insert queries in PHP in such manner that you omit the elements that have default values, MySQL will take over and add them for you.
So, say you have a table with columns id, user and comment. Let's say that comment has a default value. What I'm saying is that you can make an insert query where you'd specify just the id and user (or probably just user, if id is the primary, auto-incrementing index), and the comment will automatically receive the default value you set in your table definition.
EDIT
Whatever works best for your app design, really... See where will they be used the most and keep them there.
But a single rule I'd follow is: don't have the defaults in more than one place, especially if they're overlapping (as opposed to extending).
Related
i'm looking for an 'best practice approach' for addressing database rows. I'm using PHP.
I'm working on a settings framework. If a dev wants to know if a specific setting is set he can just call Settings::getSetting(1); and he will get the value from the users settings.
The 1 here is the ID of the corresponding database row. ID is the only key in the table and the only unique feature.
My problem is: a dev needs a value from a setting but he doesn't want to look the ID up in the DB. My absolut fav approach would be to use statics: Settings::getSetting(Settings::SETTING_FONT_SIZE);
Creating statics implies to care about a mapping and this could result in errors. (Someone is entering a new setting in DB and forgets to also add it to the mapping).
I could create dynamic constants using define() but this constants also need to be known (but it is more elegant than dealing with IDs).
Is there a way to address a specific row without caring about a mapping and with code completition inside an IDE?
If necessary, I can change the database table
thank you in advance!
EDIT:
The database table i'm talking about has two columns. The first is the ID (unique, primary, autoincrement) and the second is called 'value' and varchar.
EDIT2:
"forget this, it is not possible what your are looking for" is an acceptable answer :)
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.
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.
Imagine this... I have a field in the database titled 'current_round'. This may only be in the range of 0,1,2,3.
Through the application logic, it is impossible to get a number above 3 or less than 0 into the database.
Should there be error checking in place to see if the value is malformed (i.e. not in the range 0-3)? Or is this just unnecessary overhead? Is it OK to assume values in a database are correctly formatted/ranged etc (assuming you sanatise/evaluate correctly all user input?)
I generally don't validate all data from the database. Instead I try to enforce constraints on the database. In your case depending on the meaning of 0, 1, 2, 3 I might use a lookup table with a foreign key constraint or if they are just numeric values I might use a check constraint (differs from DB vendor to the next).
This helps protect against changes made to the DB by someone with direct access and/or future applications that may use the same DB but not share your input validation process.
Wherever you decide to place validation prior to insertion in the database is where you should catch these things.
The process of validation should take place in one place and one place only. Depending on how your application is structured:
Is it procedural or object oriented?
If it is object oriented, then are you using an Active Record pattern, Gateway pattern or Data Mapper pattern to handle your database mapping?
Do you have domain objects that are separate from your database abstraction layer?
Then you will need to decide on where to place this logic in your application.
In my case, domain objects contain the validation logic and functions with data mappers that actually perform the insert and update functions to the database. So before I ever attempt to save information to the database, I confirm that there are valid values.
Get the database to do this for you. Most advanced DBMS (check out free DB2 Express-C at http://FreeDB2.com) allow you to define constraints. This way you are getting the database to ensure semantic integrity of your data. Getting this done in application code will work at the beginning but you will invariably find down the line that it will stop working for various reasons. You may have additional applications populate data in to the database or you may get a bug creeping in to existing app. The thing that happens most often is you get new people to work on the application and they will add code that will fail to perform the same level of checking that you have done.
In general, you should check for what you're expecting, either value or type. And act appropriately. Only after it fails all checks should maybe some code think about working out what to do with the 'wrong' value and how to fix things. This applies with a state value, like what you have, or with an input type that needs to be the correct type.
The constraints should be put on the database, just remember to catch any exceptions thrown if your application would by any chance try to insert/update an invalid value