What data type use for taxrate field - sql

What data type should I use for tax rate field in my RoR application. I want it to store only numbers from 0 to 100 and two fixed strings "zw" and "np". Should I use string type and parse it to integer when it's number?

I think, perhaps, you should think about the tax rate as a name of the rate rather than a numeric value.
Create a reference table of tax rates, something like:
create table TaxRates (
TaxRateId int primary key, -- auto_increment/serial/identity
Name varchar(255) not null unique,
Value int, -- NULL if not appropriate
<more columns if necessary>
);
The drop-down list can use this table for the names. Most of the names will be numbers, but that is ok. The actual numeric value will be in the Value field (which you might really want to be a decimal).
Any table that uses a tax rate would have a foreign key reference to TaxRateId.

Related

SQL Table with mixed data type field Best Practice

everyone,
I would like an advice on best practice for creating realtional database structure with field having mixed data type.
I have 'datasets' (some business objects) and I would like to have list of parameters, associated with each dataset. And those parameters can have different types - strings, integers, float and json values.
What would be the best structure for the parameters table? Should I have single column with string type?
CREATE TABLE param_desc (
id serial PRIMARY KEY,
name varchar NOT NULL,
param_type int -- varchar, int, real, json
);
CREATE TABLE param_value (
id serial PRIMARY KEY,
dataset_id int NOT NULL,
param int NOT NULL REFERENCES param_desc (id),
value varchar NOT NULL,
CONSTRAINT _param_object_id_param_name_id_time_from_key UNIQUE (dataset_id, param)
);
The problem with such approach is that I can't easily cast value for some additional conditions. For example, I want to get all datasets with some specific integer parameter, having int value more than 10. But if I write where clause, the casting will return error, as other non-integer parameters can't be casted.
SELECT dataset_id FROM vw_param_current WHERE name = 'priority' AND value::int > 5
Or should I have 4 separate columns, with 3 of them being NULL for every row?
Or should I have 4 different tables?

Currency exchange in database

I am designing a relational database that includes currency exchange rates. My first intuition was to have a currency table that lists all the currencies and holding as attributes the exchange rate for every other currency.
Ex:
Currency Table
id INT
base_currency_code VARCHAR
date DATE
USD DECIMAL
GBP DECIMAL
EUR DECIMAL
I've done a search online on how currency exchange tables are implemented in databases, and everywhere I've looked instead has a table currency_exchange with columns base_currency, non_base_currency (to currency), rate, and date.
Since I can't find an implementation similar to mine and since one post I read said the other implementation is how it's done at the financial company he works at, I assume that the other is superior to mine!
I just don't understand why. Could someone please explain why the other is better?
You want tables like something this:
create table Currencies (
CurrencyId int primary key,
ISO_Code varchar(3),
Name varchar(255)
);
create table CurrencyExchangerate (
CurrencyExchangerateId int primary key,
FromCurrencyId int not null references Currencies(CurrencyId),
ToCurrencyId int not null references Currencies(CurrencyId),
RateDate date not null,
ExchangeRate decimal(20, 10),
constraint unq_currencyexchangerate_3 unique (FromCurrencyId, ToCurrencyId, RateDate)
);

Save filter criteria on a SQL database

I have a Products table as follows:
create table dbo.Product (
Id int not null
Name nvarchar (80) not null,
Price decimal not null
)
I am creating Baskets (lists of products) as follows:
create table dbo.Baskets (
Id int not null
Name nvarchar (80) not null
)
create table dbo.BasketProducts (
BasketId int not null,
ProductId int not null,
)
A basket is created based on a Search Criteria using parameters:
MinimumPrice;
MaximumPrice;
Categories (can be zero to many);
MinimumWarrantyPeriod
I need to save these parameters so later I know how the basket was created.
In the future I will have more parameters so I see 2 options:
Add MinimumPrice, MaximumPrice and MinimumWarrantyPeriod as columns to Basket table and add a BasketCategories and Categories tables to relate a Basket to Categories.
Create a more flexible design using a Parameters table:
create table dbo.BasketParameters (
BasketId int not null,
ParameterTypeId int not null,
Value nvarchar (400) not null
)
create table dbo.ParameterType (
Id int not null
Name nvarchar (80) not null
)
Parameter types are MinimumPrice, MaximumPrice, Categories, MinimumWarrantyPeriod, etc.
So for each Basket I have a list of BasketParameters, all different, having each on value. Later if I need for parameter types I add them to the ParameterType table ...
The application will be responsible for using each Basket Parameters to build the Basket ... I will have, for example, a Categories table but will be decoupled from the BasketParameters.
Does this make sense? Which approach would you use?
Your first option is superior (especially since you are using a relational data store. I.e. SQL Server), since it is properly referential. This will be much easier to maintain and query as well as far more performant.
Your second solution is equivalent to an EVA table: https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
Which are usually a terrible idea (and if you need that type of flexibility you should probably use a Document Database or other NoSQL Solution instead). The only benefit to this is if you need to add/remove attributes regularly or based on other criteria.

Primary Key problems when importing

I am building a database and have set field A, Release #, as the primary field. I am running into a problem where duplicate keys are found which gives error on import.
Specifically, release # "49221" is the value of a certain release from a certain website. On a different website, the release # is "0000000049221"
Release# 49221 is a completely different release than is "0000000049221". Is there a way for me to import both of them into the same table while still retaining field "release #" as the primary key?
This usually happens when implicit conversions are given, check the type of your primary key.
For example:
CREATE TABLE TEST
(
COLUMN_1 INT,
COLUMN_2 VARCHAR(8)
)
INSERT INTO TEST
VALUES (4566,'00004566')
SELECT * FROM TEST WHERE COLUMN_1 = COLUMN_2
The second column , it converts to int, and the zeros at the left dissapear, Because zeros at the left in a number has not value (as you know).
Change the second column type to type varchar or char.
You would need to define the primary key as a CHAR or VARCHAR instead of an integer value.

SQL - Create table in SQL

Please guide me if I'm on right track.
I'm trying to create database schema for Mobile Bill for a person X and how to define PK, FK for the table Bill_Detail_Lines.
Here are the assumptions:
Every customer will have a unique relationship number.
Bill_no will be unique as it is generated every month.
X can call to the same mobile no every month.
Account_no is associated with every mobile no and it doesn't change.
Schema:
table: Bill_Headers
Relationship_no - int, NOT NULL , PK
Bill_no - int, NOT NULL , PK
Bill_date - varchar(255), NOT NULL
Bill_charges - int, NOT NULL
table: Bill_Detail_Lines
Account_no - int, NOT NULL
Bill_no - int, NOT NULL , FK
Relationship_no - int, NOT NULL, FK
Phone_no - int, NOT NULL
Total_charges - int
table: Customers
Relationship_no - int, NOT NULL, PK
Customer_name - varchar(255)
Address_line_1 - varchar(255)
Address_line_2 - varchar(255)
Address_line_3 - varchar(255)
City - varchar(255)
State - varchar(255)
Country - varchar(255)
I would recommend having a primary key for Bill_Detail_Lines. If each line represents a total of all calls made to a given number, then the natural PK seems to be (Relationship_no, Bill_no, Phone_no), or maybe (Relationship_no, Bill_no, Account_no).
If each line instead represents a single call, then I would probably add a Line_no column and make the PK (Relationship_no, Bill_no, Line_no).
Yes, as for me, everything looks good.
I have to disagree, there's a couple of 'standards' which aren't being followed. Yes the design looks ok, but the naming convention isn't appropriate.
Firstly, table names should be singular (many people will disagree with this).
If you have a single int, PK on a table, the standard is to call it 'ID', thus you have "SELECT Customer.ID FROM Customer" - for instance. You also then fully qualify the FK columns, for instance: CustomerID on Bill_Headers instead of Relationship_no which you then have to check in the table definition to remember what it's related to.
Something I also always keep in mind, is to make the column header as clear and short as possible without obfuscating the name. For instance, "Bill_charges" on Bill_Headers could just be "Charges", as you're already on the Bill_Header(s) (<- damn that 's'), same goes for Date, but date could be a bit more descriptive, CreatedDate, LastUpdatedDate, etc...
Lastly, beware of hard-coding multiple columns where one would suffice, same other way around. Specifically I'm talking about:
Address_line_1 - varchar(255)
Address_line_2 - varchar(255)
Address_line_3 - varchar(255)
This will lead to headaches later. SQL does have the capability to store new line characters in a string, thus combining them to one "Address - varchar(8000)" would be easiest. Ideally this would be in a separate table, call it Customer_Address with int "CustomerID - int PK FK" column where you can enter specific information.
Remember, these are just suggestions as there's no single way of database design that everyone SHOULD follow. These are best practices, at the end of the day it's your decision to make.
There are a few mistakes:
Realtionship_no and Bill_no are int. Make sure that the entries are within the range of integer. It is better to take them as varchar() or char()
Bill_date should be in data type Date
In table Bill_Detail_Lines also, it is better to have Account_no as varchar() or char() because of the long account no. And the same goes with Phone_no.
Your Customers table is all fine except that you have taken varchar() size as 255 for City State and Country which is too large. You can work with smaller size also.