Automatical creation of indentity(1,1) but with GUIDs instead of integers - sql

A neat thingy is to put identity(2,3) on a column to get the counter and an unique value to index. I wonder if, and in such case how, it's possible to do the same with a guid.
So, instead of inserting a row with newid(), I'd have one created for me.
If there's no way to do that, I'd like to know the technical rationale behind it. If there is any, of course.
create table Records (
Id int identity(3,14) primary key,
Occasion datetime not null,
Amount float not null,
Mileage int not null,
Information varchar(999) default ' '
)

As the lazy efficient #MartinSmith commented (but didn't bother to formulate a full-size reply, forcing me to do that for him, hehe), we can use default keyword to achieve the requested behavior as shown below.
create table Records (
Id uniqueidentifier primary key default newid(),
Occasion datetime not null,
Amount float not null,
Mileage int not null,
Information varchar(999) default ' '
)
And if the said lazy Martin wishes, he might just copy over the contents of this answer and post it as his own reply, since it was really his suggestions and I'm merely a typing machine for him. Given that he's got rep like an immortal God, I doubt he will, but still - I want to make this perfectly clear.

Related

SQL - Table structure for read/unread Notifications per user

I have a requirement to create a notification module on a web application and I would like to know which user has read the notification so I won't have to display the Red Badge that indicates that a notification is not yet read.
I have thought of two solutions.
The first one is a bit naive but I find it easier to implement and maintain:
Solution #1:
CREATE TABLE [Notifications1]
(
Id integer NOT NULL,
Title varchar(255) NOT NULL,
Description varchar(255) NOT NULL,
DateInserted datetime NOT NULL,
ReadByUsers varchar(MAX) NOT NULL
)
So in this case, when a user opens an unread notification, I will append the User ID on the ReadByUsers column, so it will look like this 10,12,15,20 ...
Then when I need to check whether the user has read the notification, I will simply query the column to see whether the user id is included.
The second solution looks more of 'best practice' approach but it gets bit more complicated and a bit more heavy I guess..
Solution #2:
CREATE TABLE [Notifications]
(
Id integer NOT NULL,
Title varchar(255) NOT NULL,
Description varchar(255) NOT NULL,
DateInserted datetime NOT NULL,
CONSTRAINT [PK_NOTIFICATIONS]
PRIMARY KEY CLUSTERED
)
CREATE TABLE [Notification_Users]
(
NotificationId integer NOT NULL,
UserId integer NOT NULL
)
In this case I store the user that has seen the notification in a different table with a relationship (One to Many) on the Notification Id on the main table. And then I can check the Notification_Users table to check if the user has seen the notification.
Also note that :
I don't need to know the time the user has seen the notification.
The application is not expected to reach more than 10000 users any time soon.
Notifications will be deleted from database after few months. So max 10 notifications at a time.
Do you have any suggestions for better implementation?
Thanks
Solution #2 would be the preferred solution.
Storing a list of Ids is not a normalized solution. In my opinion, the return on investment of breaking this out into two tables out weights the perceived complexity.
Some good info below, and honestly all over the net.
A Database "Best" Practice
https://softwareengineering.stackexchange.com/questions/358913/is-storing-a-list-of-strings-in-single-database-field-a-bad-idea-why

Representing a fixed number of repeating, independent objects in SQL table

I'm trying to represent an object with four independent points (and a variety of other properties, represented here by [...]) in SQL. A single table approach might look like this:
CREATE TABLE Object (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
[...]
Point1X float NOT NULL,
Point1Y float NOT NULL,
Point2X float NOT NULL,
Point2Y float NOT NULL,
Point3X float NOT NULL,
Point3Y float NOT NULL,
Point4X float NOT NULL,
Point4Y float NOT NULL
)
Where a multi-table approach might look more like this:
CREATE TABLE Object (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
[...]
Point1 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
Point2 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
Point3 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id),
Point4 bigint NOT NULL FOREIGN KEY REFERENCES Point(Id)
)
CREATE TABLE Point (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
XCoord float NOT NULL,
YCoord float NOT NULL
)
The second approach looks far more elegant coming from an OO design background, but at the same time I can already see how it will be a bit more difficult to work with when updating the objects in question inside my ORM and I don't like the number of FK constraints I'm adding. The first option looks very cluttered, and it also means that I will not be able to add other properties to the points after the fact (say, if I wanted to assign a Color to each point in six month's time).
I would also say that there's a third option, where the Points table maintains a foreign key reference back to the Object, which means that an object may now have any number of points. I don't like this option as much. For the current scope of the project an object will only ever have exactly four points, so that constraint would then have to be dealt with on my application layer, and it makes dealing with the relation inside the ORM even more difficult.
What's the correct way to work out a design like this?
EDIT: A few more details:
Points are representing the midpoint of each side of a rectangle - imagine a cross-like shape.
It's important to know which points are across from each other - hence having a center defined, or having some kind of ordering (point1 is always directly across from point3, for instance).
Aside from the above constraint, there is no ordering of points.
At the moment I will only be querying for objects and then drawing their points, not running queries against the points themselves, although I could see this being a requirement in the future.
Objects shouldn't overlap, but this isn't a hard constraint in the system.
Objects likewise shouldn't share the same four points. Since the points are floats (at least, in this example - I'm open to better suggestions for datatypes) and are originally taken from user input (think mouse cursor positions on a canvas) I don't think it's very likely that any two objects will ever share any points.
This is more opinion that a statement of the right way to model this problem.
You have 3 potential designs. I'll call them
Single Table
Two Table
Three table (Matt's answer).
The key factors, in my mind are:
Will there be a need to generalize relationship between objects and points to a 1 to N relationship? Will the relationship always be 1 to 4?
Will there be a need to work with points outside the context of objects? Such as the need to query all points within a given range?
If the answer to those 2 questions are no/no, then I would go with solution 1, and leave the compositional model in the OO space, giving the OO/DB mapping layer the task of decomposing the object graph into 1 row in 1 table. Yes the column defs don't look elegant, but once the table is in place everything should be easier to work with. No Joins. No FKs. No potential to accidentally create an object with only 2 points. You will likely get the best performance with this solution as well.
If the answer to either of the above questions is yes, I would choose option #3, although I think the association table needs another field to specify how a point relates to the object (i.e. Point #1/#3 or Point #2/#4). No doubt Matt was unaware of that requirement when he crafted his answer.
This is not an uncommon design decision.
Between your two approaches, I prefer the second. The reason is simple. If you have four of "something" then that "something" sounds like an entity. In a relational model, an entity should have its own table.
However, you reject my actual preferred option, which is to have a foreign key reference back to the original objects. The only issue is enforcing the number constraint. You can do that by using a trigger to maintain the count and rejecting any attempt to insert a fifth point. I am not thrilled with the need to use a trigger, but SQL isn't always powerful enough to represent everything we want to represent directly.
CREATE TABLE Object (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
[...]
)
CREATE TABLE Point (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
XCoord float NOT NULL,
YCoord float NOT NULL
)
CREATE TABLE ObjectPointCrossRef (
Id bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
,ObjectId bigint NOT NULL
,PointId bigint NOT NULL
)
I understand this structure isn't as nice from an application programming standpoint but as far as a data standpoint and flexibility to accommodate application requirement changes it works nicely. Also if you commonly share points between objects this might lead to a space savings because multiple objects can reference the same point... Take the example of now needing 5 points (pentagon) no programming changes are needed [I know you said that won't happen but I can only assume you are allowing rectangles of some kind.... Or perhaps adding a color to only 1 objects point add a color to the Cross Reference table.

SQL - Storing undefined fields in a table

So, I have a few client that want to store user data, the thing is they want to store data without telling me what it is. What I mean is that, they will likely store things like username, first name, last name and email, but then there are a myriad of other things that are no defined and that can change.
So with that in mind, I want to create a table that can handle that data. I was thinking of setting up a table like this:
CREATE TABLE [dbo].[Details](
[Id] [int] NOT NULL,
[ClientId] [nvarchar](128) NOT NULL,
[ColumnName] [nvarchar](255) NOT NULL,
[ColumnValue] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_Details] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
Is this the best way to store this data, or am I making a mistake?
Please help me before I go ahead and create this table! :D
Just make clear to your clients that fields the database knows about, like a user number, name, and address can be searched fast, checked for consistency, and even be used for program control (such as some users see or can do what others cannot), whereas "undefined data" will not.
Then find out, if they really need single entities. Then the name/value approach is exactly the way to go. Maybe, however, it suffices to store one note per user, where they enter all their comments, memos, etc., i.e. just one text to hold all "undefined data". If possible this would be a better approach.

SQL/DB design: multi-column foreign key with mixed NULL/NOT NULL treated as mandatory or optional?

In DB design/SQL is it theoretically possible to declare something like that:
CREATE TABLE Groups
(
round_id INTEGER NOT NULL,
ordinal_nbr SMALLINT NOT NULL,
PRIMARY KEY (round_id, ordinal_nbr),
FOREIGN KEY (round_id) REFERENCES Rounds (id) /* irrelevant, just a reference to another table's ID */
)
CREATE TABLE Games
(
id INTEGER NOT NULL IDENTITY,
round_id INTEGER NOT NULL, /* !!! */
ordinal_nbr SMALLINT NULL, /* !!! */
scheduled_tipoff DATETIME NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (round_id, ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr) /* multi-column FK round_id NOT NULL, ordinal_nbr NULL */
)
Now the question:
Since this has to be considered rather a programming mistake, what is the best thing to adjust for such scenarios: treat such FK's as mandatory or treat them as optional?
What would be a logical policy here?
As I'm thinking about it it seems to make more sense to consider the whole FK rather optional. As soon as one piece of information is missing, whether intended or not, the whole FK depends on the column(s) whose value hasn't been set YET.
After all, the NULL destroys obligation. It makes more sense to me than the other way around.
I don't think there's a general answer to that. In the existing data, are there any null values in games.ordinal_nbr? There might be code out there that expects to be able to put a null in there, so you have check all the code that uses that table. Even more fun is different databases handle that in different ways. Some consider "null = null" to be true while others consider any comparison operator false if either side is null even if both are.
Nullable foreign keys in SQL have plenty of disadvantages. From a semantic modelling perspective it is unlikely to make sense. For example suppose the intended meaning of a null ordinal_nbr is that that attribute is unknown. In that case SQL may not evaluate the other attribute and won't return an error even if there is no matching row for the known value of round_id (YMMV depending on DBMS and other options).
I suggest you redesign it so as to eliminate all nullable foreign keys.
Why does it have to be a mistake?
Consider a Adults table and a Offspring table that references it.
(mis-stated previously) edit:
What if there were Offspring that you did know the parents of? Just ignore that they exist.
edit:
This is a real example I just encountered recently:
I am basing my database against a de-normalized source where I have no control over the data. A key referencing the owners table should be required logically. Running a query I came across an owner name that was:
'UNKOWN OWNER'
Hmm, that could floated around for a long time and it was only chance that I caught it. I run aggregate queries against the owner table where things like that will give me incorrect results. The designers of that database traded in the 'enormous complexity' of dealing with nulls by hiding it with their own brand of null.
If the value was blank or null it would raised an error immediately and I could changed the table in the beginning of the design. Also, in aggregate queries nulls fall out of joins so you do not have incorrect results. And when I want them I just left join the tables.
Create a single Field in your Groups table to act as the primary key and join on that..
You have an administrative nightmare here.
NULL<>NULL!!!!!
If X is Unknown and Y is Unknown can you say X=Y?
Depending on the you DB\ Configuration the Join may even fail.. an in my option the fact that any DB allows NUll=NULL to return True is a Mistake.

sql boolean datatype alternatives

What are the situations when you would use a foreign key to a separate table rather than use a boolean (i.e. BIT in SQL Server)
For example would you replace the following two booleans in this table:
engine_sensors
--------------
id (int, primary key)
name (varchar(50))
fault_code (int)
display_warning (boolean) /* if fault show driver a warning */
is_test_sensor (boolean) /* ignore this sensor in diagnostic checks */
e.g. display_warning here might not display the warning to a driver but do display a warning to a mechanic who is testing the engine. So a separate table would be appropriate.
is_test_sensor could be replaced by sensor_type (FK to sensor_types table) which has types of test,live.
If the fields model a boolean value, I would leave them as booleans. That's why they exist.
I would not attempt to future proof my database design (YAGNI principle), you can always change it at a later date.
This depends why you'd want to avoid it. You could just have number fields with 0 for false and 1 for true. Not sure if there are any benefits though.
Np. Now I see what you are getting at (I think).
If you are asking what I think you are asking than yes, you might want to use a FK to a sensor table and list the sensors. This is typically what I would do...
CREATE TABLE [SensorType](
[Id] [int] NOT NULL,
[Type] [int] NOT NULL,
[DisplayWarningTo] [int] NOT NULL,
[Description] [nvarchar](100) NULL,
CONSTRAINT [PK_SensorType_Id] PRIMARY KEY (Id),
CONSTRAINT [FK_SensorType_WarningReceivor] FOREIGN KEY (DisplayWarningTo) REFERENCES WarningReceivor(Id)
);
CREATE TABLE [WarningReceiver](
[Id] [int] NOT NULL,
[Receiver] [int] NOT NULL,
CONSTRAINT [PK_WarningReceiver_Id] PRIMARY KEY (Id)
);
------
INSERT INTO WarningReceiver(Id, Type) VALUES (1, 'Mechanic');
INSERT INTO WarningReceiver(Id, Type) VALUES (2, 'Driver');
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (1, 'Rear sensor', 2);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (2, 'Test sensor', 1);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (3, 'Production sensor', 2);
I tend not to use identity columns on 'type' things like this and specify my own id which I map directly to a C# enumerated constant like
public enum SensorType
{
RearSensor = 1,
TestSensor = 2,
ProductionSensor = 3
}
Then in your code when you pull out your engine sensor from the database you can just compare against your enum. e.g.
var engine_sensor = // get engine sensor from db.
if (engine_sensor == (int)SensorType.RearSensor)
{
// do something
}
else if (engine_sensor == (int)SensorType.TestSensor)
{
// display something to mechanic or whatever
}
I don't really know what your application domain is, so sorry if this doesn't make sense.
So to wrap up a couple of points and try and answer your question;
Yes I do think you are better off with FK's
You could just have them as int columns and define the sensors in code as I did with the enum
I tend to do both
--- define the enum for nice strong typing in code and
--- create a foreign key table to complete my schema in the database. It's still worth having this for two reasons; 1) When writing sql queries in management studio or something and your looking at your engine_sensors table and see numbers for the sensor type you can join on your FK table to see what the sensors are. Makes things a bit easier
Lastly, if you have a FK table it enforces referential integrity and restricts the values you can put in as sensor types to what you have defined in the sensor type table.
Hope this helps somewhat.
You have added one piece of information
'Its is a SQL Server database and I understand that you'd use a bit field. I was wondering on how bad an idea it is to replace them with foreign keys to a separate table'
You should edit your original question and put this in if this is important to the solution you seek so that more people will be able to easily find it.
But you still haven't said why you were wondering about replacing them with a FK. If you tell people what your end goal is or what you are trying to achieve, they are more likely to provide a range of solutions.
I'm sorry I can't suggest a solution. Is a foreign key (to what?) better than a boolean value? compared to ?
I think you need to clarify / re-structure your question a bit. Good luck.
engine_sensors
id (primary key)
name
fault_code
display_warning_engine_sensors /* if fault show driver a warning */
id (primary key, FK to engine_sensors)
test_sensors /* ignore this sensor in diagnostic checks */
id (primary key, FK to engine_sensors)
Remember : codes are poor, tables are rich. Regardless of how contradictory this seems : never use booleans to represent truth-valued information. The relational model already has a way for representing truth-valued information, and that is as the presence of some tuple in some relation that is the value of some relvar (in SQL terms : as the presence of some row in a table).
You cannot easily "extend" booleans to add extra functionality such as "display a warning only if the time is within the range [x hrs - y hrs].
Relational theory can help to answer the questions for you. WHERE the booleans go (in the table as shown or in a separate table as described in your example) should be determined by what the boolean data element is dependent (and fully dependent) on.
For example, if the data element "display_warning" depends only on the sensor (the entity your table is describing), then that column belongs in that table. However if it depends on other entities (the person - owner or mechanic - interacting with the sensor), then it more properly belongs in a different table where it can be fully and only dependent on the primary key of that table.
Ensuring that the data elements are dependent on the key (and nothing other than the key) is arrived at through "normalization" of the data. It's much to envolved to include in an answer here, but there are many references on the web that will help you to understand normalization more fully. Wikipedia is as good a place to start as any:
http://en.wikipedia.org/wiki/Database_normalization#Normal_forms
Indexing is one reason to avoid boolean types. You can;t index boolean fields, so if you have many records and search often on the fields that are boolean, having a separate table might be helpful. A separate sensor type table is also more extensible if you add more types. It is also helpful if there becomes a one to many relationships for a particular sensor type. Suppose an engine needed to have three of a particular type of sensor.
Using 'bit' in SQL server (0 or 1) will automatically map back to a boolean in linq to SQL if you still wanted a boolean in your code.
But you haven't stated what database or why you want an alternative to bool.
First, I'd like to confirm Oded. If you need boolean values you should use the responsible column types.
However, if you have to store very much different boolean values it is sometimes more useful to use old-school bit-masks, stored in an INT, BIGINT or even BINARY column.