Frontpage

sys-db-user-data

Mål

Lagra användarens data, möjliggöra och förhindra åtkomst av data.

Effekt

Omarbetad version

-- Ett datablock
{
row_uuid:UUIDv7,
user_id:RAND(INT),
data_state:TINYINT,
data_subtype:SMALLINT, 
data:BLOB, -- regardless of binary or text content, choose BLOB.
}

Analys/Applicering

  • Klient genererar UUIDv7.
  • UUIDv7 ger tidsbaserade id.
  • Server genererar användares ID vid konto-skapande.
  • Om saknas: Klient laddar ner hela sin databas inom ett tidsspann och lagrar som lokal kopia.
  • Klient CRUD på enskild rad via UUID.
  • Databas registrerar datablockets status: insatt, uppdaterad, raderad.
  • Klient kan sätta och söka på egen-definierad datatyp för datablock.
  • UUIDv7 som primär nyckel gör klienten oberoende av servern i skapande av data och vi slipper komplicerad placeholder-lösningar för ID.
  • Permissions-kontroll ska ingå då det faller i kategori "tillkomst av data" vilket är del av målet.

Negation

  • Databasen ska inte se relationer mellan data. Bara CRUD aktiviteter. Är det uppnått?
  • Försvårar den realtids-synk?
  • Försvårar den permissions-kontroll och annat i kollaborativ miljö?
  • Gör den mer än den ska och anpassar sig specifikt efter något? -
  • data_type ogillas, varför ska databasen ha separat fält för klientens valda datatyper, kan du inte ta bort den. Nej. Det är del av struktur för tillgång av data, inte för association av data på server så som i JOIN aktiviteter, så målet med en "blind" databas är bevarat.
  • Är alla kolumn-typer optimala.
  • Är databasen optimal med hänsyn till innehållets form. ❌ Nej. Inte optimalt med en tabell för all data.

Åtgärder

  • data_type borttaget.
  • varje modul (plugin) registrerar sina data-typer och har egen tabell för sin data. Matlistan är en modul med en tabell, användar-inställningar är en annan modul med egen tabell.
  • Vi har två typer av data. 1) Sådant som vi vill tillgå via tidsspann (ex. senaste registrerade värdena), 2) sådant som vi vill tillgå via användar-id (returnerar då all användarens data, and ex. alla matprodukter). Tabellerna kan då indexeras/optimeras efter åtkomst-typ, dvs på uuid (rad-id) eller userid. Flera fördelar finns.
  • Varje modul har därför antingen eller både tabell_[modul-id][a|b]. Ex. table_1a, table_1b.
  • Introducera data_subtype för att ge modul möjlighet till segmentering efter eget behov.

Negation rond 2

  • Realtidssynk blir plugin, det är bra, håller sig utanför målet för denna modul. Dvs databasen anpassar sig inte särskilt efter synk. Den är samma för alla moduler.
  • Bättre optimerat: En tabell på miljoner rader blir nu uppdelad i många tabeller. God databas-sed, underlättar indexering, and caching, and sökning etc.
  • Alla tabeller är uniforma, enkelt och bra. Ingen särbehandling med modul-specifika kolumner. Klient lagrar specifik data i BLOBen och strukturerar på klientsidan. Databas på server bryr sig inte om specifik struktur.
  • Bra: fortfarande CRUD.

Livstips: Liksom modulen-designen ovanför; känn dig själv och gör din sak väl och kompromissa med andra som förskjuter sitt ansvar åt ditt håll. Låt andra ta ansvar för sin egen måluppfyllelse och att hålla det inom sin egen sfär. Föregå med gott exempel och inspirera andra att definiera sitt mål och själva hitta och utföra handlingar i den riktningen, men gör det inte åt dem.

  • Permissions-kontroll, hur ska du göra där?
  • Hur göra med kryptering-versionen i kolaborativ miljö?

Åtgärd rond 2

Permission - en användare kan ge en eller flera användare tillgång till viss data.

Separat tabell:

table permissions
{
owner_id: INT,
subject_table: TINYINT,
data_subtype: SMALINT DEFAULT NULL, 
from: DATETIME DEFAULT NULL, 
to: DATETIME DEFAULT NULL, 
read: BOOL, 
write: BOOL, 
users_granted: JSON
}
  • Om from eller to är NULL, då ingen gräns i den riktningen.
  • Om data_subtype är NULL, då tillgång till alla typer.
  • Aktiva användares permissions-tabell kan läggas som ett kontroll-lager i Redis, med fallback på databas. Eller bättre: Redis csching av permissions-tabeller.

Krypteringen:

  • Klient krypterar som vanligt om den vill. Databasen bryr sig inte om vad som lagras i BLOBen. Annan användare kan inte läsa den även om det delas.
  • Kan göra separat asymmetrisk kryptering (public-key encryption) för kolaboratov miljö (också på plugin-nivå).

Negation rond 3

  • Lösningen för realtids synk är inte helt genomtänkt.
  • Kan jag inte strunta i separat tabell för realtids synk i databasen. Skulle kräva 2 insättningar för varje enskild insättning.

Åtgärd 3

  • Använd embart Redis för realtids synk.

Använd inte Redis. Använd KeyDB istället.

  • KeyDB har stöd för "tiered storage". Om RAM minnet visar sig begränsat så nyttjar den hårddisken. I KeyDB är den funktionen fri. Redis å andra sidan kräver "Enterprise".
  • Med "tiered storage" räcker det med KeyDB för min realtidssynk-funktion. Behöver inte fallback i databasen.
  • Om KeyDB innehåll raderas (server-omstart) laddar klienterna ner data direkt från databasen.

Användaren laddar ner all sin data eller vet klienten en tidpunkt från vilken den ska ladda ner från?

  • Använd tidpunkt. Klienten vet senaste tidpunkt då den uppdaterade sin lokala databas.
  • SELECT * FROM user_data WHERE modified_at > $client_latest_update.
  • Det kräver ett nytt fält modified_at.