# Database with encrypted values
Like it was mentioned in searchable and sortable
you can still use your database to query data to the customer without the need to decrypt it first and then doing
queries like
searching for a value, getting the exact results or returning a sorted list of values.
Use searchable encryption to get either the exact data match or multiple data to a searched value
and sortable encryption to do range queries like `ORDER BY name`.
Because sortable encryption won't encrypt your full data it should not be used for exact matches.
The best thing is that you don't need to modify your database or just different functions.
Both technics can be used with the native database query functions like you would do with not encrypted data.
The example below is a relational database like mysql, sqlite or postgres but this will also work for nosql databases.
## The tables
Use a normal table for your data like you would do without encryption.
Table: user:
| 123 | Jon | Snow | 24 |
| 124 | John | Snowing | 55 |
| 125 | Johnny | Depp | 60 |
In the real world the data is end-to-end encrypted in your group. The problem, you can't do anything with it, except
storing them.
### Searchable
Create a 2nd table for the search hashes of each column you want to query and link it to your users table.
Table: user_hash:
| item_id | hash |
| 123 | `another hash of Jon` |
| 124 | `hash of John` |
| 125 | `hash of Johnny` |
Now create the hashes like this:
````rust
use sentc::keys::StdGroup;
fn example(group: &StdGroup)
{
let hashes_jon = group.create_search_raw("Jon", false, None).unwrap();
let hashes_john = group.create_search_raw("John", false, None).unwrap();
let hashes_johnny = group.create_search_raw("Johnny", false, None).unwrap();
}
````
You can also set a boolean flag in your hashes table for the last hash of a word.
The last item in the hashes list is also the hash of the exact word.
This helps to do queries where you need the equal value and not all values like this.
| 123 | `hash of Jon` | false |
| 123 | `another hash of Jon` | true |
| 124 | `hash of John` | false |
| 125 | `hash of Johnny` | false |
If you want to only got the exact values test if the last is true.
### Sort/Order able
If you also want to query the last name create a second table for the hashes of the last name
or create a column with a flag that identifies to what column the hash is for, for the id.
To do range queries expand the users table by a column of a value that you want to do the range query. Like if you want
to `ORDER BY` first_name,
then create another column with the sortable first_name.
| 123 | `encrypted` | `encrypted` | `encrypted` | 1267 |
| 124 | `encrypted` | `encrypted` | `encrypted` | 1268 |
| 124 | `encrypted` | `encrypted` | `encrypted` | 1269 |
Now create the sortable column like this:
````rust
use sentc::keys::StdGroup;
fn example(group: &StdGroup)
{
let sort_jon = group.encrypt_sortable_raw_string("Jon", None).unwrap();
let sort_john = group.encrypt_sortable_raw_string("John", None).unwrap();
let sort_johnny = group.encrypt_sortable_raw_string("Johnny", None).unwrap();
}
````
## Query
To get now the data just use the normal database queries.
To get all users order by name:
```sql
SELECT id, first_name, last_name, age
FROM users
ORDER BY order_first_name
```
This data can then decrypt by the group key.
To get the exact data you need to create a hash in the client first and then search it:
````rust
use sentc::keys::StdGroup;
fn example(group: &StdGroup)
{
let hash = group.search("jo").unwrap();
}
````
```sql
SELECT id, first_name, last_name, age
FROM users u,
user_hash uh
WHERE u.id = uh.item_id
AND hash = ?
```
The result would be all three users because everyone begins with `jo`. The is equal to sql LIKE queries.
To get exact values just check if it is the last hash (of the full word).
```sql
SELECT id, first_name, last_name, age
FROM users u,
user_hash uh
WHERE u.id = uh.item_id
AND last_hash = TRUE
AND hash = ?
```
For the hash of `John` only the data with id 124 will be returned but not johnny (id 125).
Now you still get the ability to do search queries and exact matches. With createSearch option full you can't do
searching.