HTML

Projektmenedzsment, alkalmazásfejlesztés

Online projektmenedzsment rendszerek, webes alkalmazások fejlesztése, refactoring.

Friss topikok

Linkblog

Boolean mezők kezelése

2010.08.06. 21:40 develop

Néha találkozok olyan alkalmazással, ami az adatbázban található boolean (logikai) típusú mezőnek a logikai viselkedésen túl, további szerepet próbál adni.

Egy boolean típusú mező igaz, vagy hamis értéket tárol, igaz, az "értéke" NULL is lehet.

A fejlesztés során azonban törekednünk kell arra, hogy az alkalmazást felépítő minden összetevő működése konzekvensen ugyanarra a logikára épüljön. (Ez segíti az alkalmazás folyamatainak könnyebb megértését.) 

Ez a szemléket egy logikai mező esetében azt jelenti, hogy a mező csak igaz vagy csak hamis értéket vegyen fel. (Ha ezektől eltérő, akkor tekintsük hibásnak az algoritmusunk.)

Szerencsére az alapértelmezett érték megadása segíthet a problémában.

Egy meglévő alkalmazásnál talált NULL érték esetében, nem tudjuk, hogyan változik meg a rekord "viselkedése" azzal, ha igazra, vagy éppen hamisra változtatjuk azt.

Lekérdezések

Sajnos a lekérdezéseink is bonyolódhatnak a boolean mezők true/false/NULL értékeitől függően.

A lekérdezéseknél mindig azt fogalmazzuk meg, hogy milyen értékű rekordokat keresünk. (És ne azt, hogy milyen rekordokat NEM keresünk.)

Vegyünk egy könyvtári kölcsönzési alkalmazást, két példával

A könyveket a book nevű tábla tárolja, minden könyvhöz egy-egy rekordot. A táblában egy is_kolcsonozheto (direkt írtam magyarul; lásd: Elnevezési ajánlások) nevű mező jelöli, hogy a könyv kölcsönözhető-e (igaz értékkel), vagy sem (hamis értékkel).

1. Kigyűjtöm a kölcsönözhető könyveket:
SELECT * FROM book WHERE is_kolcsonozheto IS TRUE;(Írhattam volna - hibásan - azt is, hogy "WHERE is_kolcsonozheto IS NOT FALSE AND is_kolcsonozheto IS NOT NULL", ami bár ugyanazokat a rekordokat gyűjti ki, de ezt sokkal nehezebb megérteni, ráadásul a fenti példa teljesen egyértelmű, mivel a kölcsönözhető, nem pedig a NEM nem kölcsönözhető és NEM nem NULL értékűeket keresem.)

2. Valamint az éppen nem elérhető könyvek listája:SELECT * FROM book WHERE is_kolcsonozheto IS FALSE;

Két hibát is vétettem!

1. Azt írtam: "nem elérhető". A mező nevét figyelembe véve ez hibás megfogalmazás, mivel az eredeti "köcsönzés" logikára épülő folyamat helyett egy eddig nem említett, "elérhető" tulajdonságot írtam.

2. A mező nevéből arra következtethetünk, hogy igaz értékkel jelöljük a kölcsönözhető könyveket. A logikát követve azokat a könyveket, amik nem kölcsönözhetőek "NOT TRUE"-val kellene lekérdezni.

A 2. példa újra - most már helyesen

2. Valmint az éppen nem kölcsönözhető könyvek listája:

SELECT * FROM book WHERE is_kolcsonozheto IS NOT TRUE;

Ha specifikációt írunk, figyeljünk, hogy fogalmazunk.

Továbbfejlesztés

Készen is vagyunk... legalábbis azt gondoltuk

Az idő múlásával bizonyos könyveket - mivel meg vannak rongálódva -, szeretnének leselejtezni (jobb esetben kisebb könyvtárak részére elajándékozni).

Lényeg: a selejtezett könyveket nem lehet kikölcsönözni, sőt, ezek nincsenek is a raktárban!

Eljárhatnánk úgy is, hogy töröljük ezeket a rekordokat [könyveket], de mivel meg akarjuk tartani, hogy korábban ki mit kölcsönzött, ezt nem tehetjük meg.

Vagyis: a könyveket meg kell tartani az adatbázisban, de nem szabad, hogy növeljék a raktárkészletet (mivel fizikailag nincsenek ott).

Ha követtük a fenti ajánlásokat, akkor a kölcsönözhetőséget igaz értékkel jelöljük, így minden "nem igaz" állapot (beleértve a FALSE, és a NULL-t is) nem kölcsönözhetőséget jelent, vagyis a könyvet nem lehet kikölcsönözni.

Összefoglalva

Az is_kolcsonozheto mező értékét "továbbgondolva":

  • igaz, ha a könyv kölcsönözhető,
  • hamis, ha a könyv nem kölcsönözhető,
  • NULL, ha a könyvet leselejtezték.

Sajnos a NULL érték miatt az is_kolcsonozheto mezővel kapcsolatos logikánk a továbbiakban már nem helyes.

kölcsönözhető állapotot tároló mezőt ugyanis így új tulajdonsággal "ruháztuk" fel.

A csak az adatbázist nézve, a mező nevéből, és a NULL értékből nem gondolunk - honnan is gondolnánk - a "selejtezettség" állapotára; ezt a "logikát" a továbbiakban már csak az algoritmusból tudnánk kideríteni. (Azt, hogy ez a specifikációban nem lesz rögzítve, biztosra vehetjük.)

Megoldást jelentene, ha átneveznénk a mezőt egy olyan kifejezésre, ami magában foglalja mind a kölcsönözhetőséget, mind pedig a selejtezettség állapotát - várom az ötleteket -, viszont nem ez a helyes út

A megoldás

Hagyjuk érintetlenül a mező nevét - így a logikát is -, valamint értékének igaz/hamis jelentését.

A "selejtezett" tulajdonság tárolására vegyünk fel egy "is_selejtezett" mezőt, az alábbi tulajdonságokkal:

  • típusa: logikai (boolean)
  • alapértelmezett értéke: hamis

Ha követjük a boolean mezőkkel kapcsolatos ajánlást, akkor a book táblában igaz értékekkel találjuk meg a selejtezettek könyveket, és nem igaz értékkel - helyes logika esetén hamis-al - azokat, amik nem selejtezettek (vagyis elviekben kikölcsönözhetőek).

Végeredmény

A logika azt diktálja, hogy:

  • mivel a selejtezett könyvet nem lehet kikölcsönözni - nincs fizikailag a raktárban -, az is_kolcsonozheto mező értéke egyértelműen hamis,
  • ha egy könyv selejtezésre kerül, akkor az is_selejtezett mező szintén hamis.

1. kiegészítés: ha megírjuk a selejtezés funkciót, ne felejtsük el mindkét mezőt hamis-ra állítani, mivel nem lehetünk benne biztosak, hogy az is_kolcsonozheto mező bizonyosan hamis: előfordulhat ugyanis, hogy valakinél olyan régen van kint a könyv, hogy egy idő után "lemondanak" róla.

2. kiegészítés: ha tovább gondolkodunk, akkor ilyen módon hibásan tároljuk a vissza nem hozott könyvek állapotát, az eddig a selejtezett könyveket jelölő is_selejtezett mezőben. :)

Ezt a problémát viszont egyszerűen megoldhatjuk:

1. a mezőt átnevezhetjük (ez is refactoring) - pl. is_nem_elerheto-re. (Figyeljük meg, hogy a névben használtuk a "nem" kifejezést, ami tiltásra utal, vagyis, ha egy könyv nem elérhető, akkor igaz az értéke. Az új mező default értéke természetesen: hamis.)

2. felveszünk egy új mezőt - az is_nem_elerheto mellé -, is_nem_hoztak_vissza néven. (A vissza nem hozott könyvek esetében mindhárom boolean mező értéke hamis.)

A környezet ellenőrzése

Bár végül sikerült megoldást adnunk a selejtezett és a kvázi "elveszett" könyvek kezelésére, az alkalmazás egyéb, book táblához kapcsolódó algoritmusait ellenőriznünk, vagy kiegészítenünk kell:

  • a kölcsönözhető könyvek listájában nem jelenhetnek meg a nem elérhető könyvek,
  • ugyanez igaz a leltár-listával kapcsolatban is (ami elveszett, az nem lehet raktáron, sem kölcsölcsönözve; viszont lehet értelme a "honnan veszett el" kérdésnek: kölcsönzés során, vagy a raktárból?),
  • biztosítani kell, hogy az érintett könyveket "nem elérhető" státuszba tudjunk helyezni,
  • szükséges lehet még a "nem elérhető" könyvek listázása is,
  • stb.

Számadás

Egy egyszerű problémából kiindulva, összetett feladat kerekedett, amit végül logikus lépések sorozataként sikerült megoldanunk. (Ebből is látszik, hogy a megvalósítási költség-becsléskor át kell gondolnunk a teljes folyamatot.)

Fontos szempont volt, hogy - lehetőség szerint -, az eredeti logikát ne módosítsuk, hanem igyekezzünk a rendelkezésre álló adatbázis-szerkezetet "fájdalommentesen" bővíteni, így kerülve el a felesleges többletköltségeket.

Szólj hozzá!

Címkék: sql adatbázis boolean programozástechnika alkalmazásfejlesztés

A bejegyzés trackback címe:

https://develop.blog.hu/api/trackback/id/tr832204455

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása