Should OPTIONAL User Settings be Lazy-Initialized into the DB or always created with a new registration?
Simple question: Should OP开发者_StackOverflowTIONAL User Settings be Lazy-Initialized into the DB or always created with a new registration?
A user can set additional settings which are optional, so should a row for that optional setting be created for every user upon registration or only created when a user makes use of those settings for the first time?
Lazy-Initialization saves space, so I'm leaning towards doing it this way, but I'm not sure if there are any drawbacks.
Do the lazy initialization. Here's why.. if you instead used default values for settings the user didn't actively choose, and then later the business rules changed to set the default to something else, you'd have users with what would appear to be non-default settings that they didn't actively choose.
Here is one particular drawback I ran into when using lazy initilization in MySQL. It all boils down to this quote from the MySQL docs:
User-defined variables are connection-specific.
First: The setup
Connect to your DB (in my case MySQL) Then create a simple function SetBarProperty() that sets the @bar property EXPLICITLY to the value passed to the function. The function itself simply returns the value passed to it.
$ mysql
mysql> DROP FUNCTION IF EXISTS SetBarProperty;
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER $$
mysql> CREATE FUNCTION SetBarProperty( myValue INT(30) )
-> RETURNS INT(30)
-> DETERMINISTIC
-> READS SQL DATA
-> BEGIN
-> SET @bar := myValue;
-> RETURN myValue;
-> END $$
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
Now if we query for the @bar property, it will be NULL just as expected.
mysql> SELECT @bar;
+------+
| @bar |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
Again, if we call the SetBarProperty(3); the result is just as expected.
mysql> SELECT SetBarProperty(3);
+-------------------+
| SetBarProperty(3) |
+-------------------+
| 3 |
+-------------------+
1 row in set (0.00 sec)
What do you think?
What do you think happens if we call the following query?
SELECT SetBarProperty(4), @bar;
You've guessed right! @bar is 4.
mysql> SELECT SetBarProperty(4), @bar;
+-------------------+------+
| SetBarProperty(4) | @bar |
+-------------------+------+
| 4 | 4 |
+-------------------+------+
1 row in set (0.00 sec)
And now the tricky part...
Disconnect from your DB server (this is very important):
Ctrl+C
Now re-connect and call the same query as before:
$ mysql
mysql> SELECT SetBarProperty(4), @bar;
+-------------------+------+
| SetBarProperty(4) | @bar |
+-------------------+------+
| 4 | NULL |
+-------------------+------+
1 row in set (0.00 sec)
Did you see what just has happened?
@bar was NULL and this is because it hasn't been initialized in the caller space of the function SetBarProperty().
If you disconnect from your DB and explicitly initialize the property BEFORE calling the function (that itself initializes it explicity) your query works just as expected:
Ctrl+C
$ mysql
mysql> SET @bar := NULL;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT SetBarProperty(4), @bar;
+-------------------+------+
| SetBarProperty(4) | @bar |
+-------------------+------+
| 4 | 4 |
+-------------------+------+
1 row in set (0.00 sec)
Recommendation
If you immediately use a property in a query just after you've called a function that modifies the same property you should initialize the property before calling the function.
I hope this helps!
Regards,
Konrad
精彩评论