{"id":262,"date":"2010-03-04T16:50:18","date_gmt":"2010-03-04T16:50:18","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/2010\/03\/04\/borrado-blando\/"},"modified":"2010-03-04T16:50:18","modified_gmt":"2010-03-04T16:50:18","slug":"borrado-blando","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2010\/03\/04\/borrado-blando\/","title":{"rendered":"Borrado blando"},"content":{"rendered":"<p>Emplando una herramienta como <a href=\"http:\/\/search.cpan.org\/dist\/DBIx-Class\/\">DBIx::Class<\/a> con un mecanismo de marcas de borrado en una base de datos relacional.<\/p>\n<p><!--more--><\/p>\n<p>Estamos a punto de dise\u00f1ar una base de datos \u00f3 una parte de una y nos encontramos en el momento en el que debemos afrontar el problema del borrado de entidades de datos. Las especificaciones dicen que tiene que ser posible deshacer cualquier operaci\u00f3n de borrado en este tipo de datos, entidades b\u00e1sicas principalmente, y queremos dise\u00f1ar un mecanismo que se encargue de ello sin complicar el mantenimiento de la aplicaci\u00f3n ni su crecimiento.<\/p>\n<p>La primera b\u00fasqueda en la red nos lleva a algunos <a href=\"http:\/\/lists.scsys.co.uk\/pipermail\/dbix-class\/2009-February\/007409.html\">hilos<\/a> y una <a href=\"http:\/\/blog.afoolishmanifesto.com\/archives\/274\">bit\u00e1cora<\/a> muy interesantes que tratan el asunto y donde se proponen varias ideas, aunque la destacable a mi juicio es la que incluye una columna extra, tipo conmutador l\u00f3gico, que se\u00f1ale si la fila est\u00e1 borrada o no. Para que funcione ser\u00e1 necesario tener en cuenta su valor en todas las b\u00fasquedas, as\u00ed como en las operaciones de creaci\u00f3n y actualizaci\u00f3n de filas.<\/p>\n<p>Pongamos por caso que definimos una tabla as\u00ed:<\/p>\n<pre><ol><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\"><span style=\"color: #993333;font-weight: bold\">CREATE<\/span> <span style=\"color: #993333;font-weight: bold\">TABLE<\/span> divisas <span style=\"color: #66cc66\">&#040;<\/span> <\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">    divisa        char<span style=\"color: #66cc66\">&#040;<\/span><span style=\"color: #cc66cc\">3<\/span><span style=\"color: #66cc66\">&#041;<\/span> <span style=\"color: #993333;font-weight: bold\">PRIMARY<\/span> <span style=\"color: #993333;font-weight: bold\">KEY<\/span>,<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">    nombre     varchar<span style=\"color: #66cc66\">&#040;<\/span><span style=\"color: #cc66cc\">100<\/span><span style=\"color: #66cc66\">&#041;<\/span> <span style=\"color: #993333;font-weight: bold\">NOT<\/span> <span style=\"color: #993333;font-weight: bold\">NULL<\/span>,<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">    valor         numeric<span style=\"color: #66cc66\">&#040;<\/span><span style=\"color: #cc66cc\">12<\/span>,<span style=\"color: #cc66cc\">2<\/span><span style=\"color: #66cc66\">&#041;<\/span> <span style=\"color: #993333;font-weight: bold\">NOT<\/span> <span style=\"color: #993333;font-weight: bold\">NULL<\/span>,<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">    _deleted   bool <span style=\"color: #993333;font-weight: bold\">DEFAULT<\/span> false<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\"><span style=\"color: #66cc66\">&#041;<\/span>;<\/div><\/li><\/ol><\/pre>\n<p>Cualquier b\u00fasqueda deber\u00e1 a\u00f1adir una cla\u00fasula especial como en:<\/p>\n<pre><ol><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\"><span style=\"color: #b1b100\">my<\/span> <span style=\"color: #0000ff\">$rs<\/span> = Alejandria-<span style=\"color: #66cc66\">&gt;<\/span><span style=\"color: #006600\">resultset<\/span><span style=\"color: #66cc66\">&#040;<\/span><span style=\"color: #ff0000\">'Divisas'<\/span><span style=\"color: #66cc66\">&#041;<\/span>-<span style=\"color: #66cc66\">&gt;<\/span><span style=\"color: #006600\">search<\/span><span style=\"color: #66cc66\">&#040;<\/span> <span style=\"color: #66cc66\">&#123;<\/span> _deleted =<span style=\"color: #66cc66\">&gt;<\/span> <span style=\"color: #cc66cc\">0<\/span> <span style=\"color: #66cc66\">&#125;<\/span> <span style=\"color: #66cc66\">&#041;<\/span>;<\/div><\/li><\/ol><\/pre>\n<p>Y ser\u00e1 tambi\u00e9n necesario cambiar los m\u00e9todos de borrado como en:<\/p>\n<pre><ol><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\"><span style=\"color: #000000;font-weight: bold\">sub<\/span> <a href=\"http:\/\/perldoc.perl.org\/functions\/delete.html\"><span style=\"color: #000066\">delete<\/span><\/a> <span style=\"color: #66cc66\">&#123;<\/span><\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">   <span style=\"color: #b1b100\">my<\/span> <span style=\"color: #0000ff\">$self<\/span> = <a href=\"http:\/\/perldoc.perl.org\/functions\/shift.html\"><span style=\"color: #000066\">shift<\/span><\/a>;<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">&nbsp;<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\">   <a href=\"http:\/\/perldoc.perl.org\/functions\/return.html\"><span style=\"color: #000066\">return<\/span><\/a> <span style=\"color: #0000ff\">$self<\/span>-<span style=\"color: #66cc66\">&gt;<\/span><span style=\"color: #006600\">update<\/span><span style=\"color: #66cc66\">&#040;<\/span><span style=\"color: #66cc66\">&#123;<\/span>   _deleted =<span style=\"color: #66cc66\">&gt;<\/span> <span style=\"color: #cc66cc\">1<\/span> <span style=\"color: #66cc66\">&#125;<\/span><span style=\"color: #66cc66\">&#041;<\/span>;<\/div><\/li><li style=\"font-family: 'Courier New', Courier, monospace;color: black;font-weight: normal;font-style: normal\"><div style=\"font-family: 'Courier New', Courier, monospace;font-weight: normal\"><span style=\"color: #66cc66\">&#125;<\/span><\/div><\/li><\/ol><\/pre>\n<h3>Inconvenientes<\/h3>\n<ol>\n<li>Dado que usamos un identificador com\u00fan como clave primaria no podremos volver a usarlo nunca porque existir\u00e1 aunque lo hayamos borrado. Esto es, si decidimos borrar la <em>libra chipriota<\/em> cuyo identificador es <em>CYP<\/em>, \u00e9ste no ser\u00e1 reutilizable nunca a menos que el borrado sea real porque una clave primaria es por definici\u00f3n un \u00edndice \u00fanico.<\/li>\n<li>La base de datos seguir\u00e1 teniendo el mismo nivel de carga borremos lo que borremos al no desaparecer f\u00edsicamente los datos.<\/li>\n<li>Las tareas de mantenimiento de la base de datos precisar\u00e1n c\u00f3digo extra y muy directo.<\/li>\n<\/ol>\n<h3>Ventajas<\/h3>\n<ol>\n<li>Existe la posibilidad de <em>resucitar<\/em> datos muy r\u00e1pidamente.<\/li>\n<li>Se mantiene la integridad referencial al no eliminarse las filas realmente.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Emplando una herramienta como DBIx::Class con un mecanismo de marcas de borrado en una base de datos relacional.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[2],"tags":[79,17],"class_list":["post-262","post","type-post","status-publish","format-standard","hentry","category-software","tag-bases-de-datos","tag-perl"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/262","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=262"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/262\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}