Duda sobre eficiencia

Iniciado por _LooSeR_, 7 Febrero 2011, 01:08 AM

0 Miembros y 1 Visitante están viendo este tema.

_LooSeR_

Hola a todos!

Estoy desarrollando una aplicación web que consiste en una red social (tipo Tuenti, Facebook) sencilla.

Ya había entregado para un trabajo de la universidad una versión muy "cutre" y para evitar complicación con la base de datos fija. Es decir tenía una tabla para todas las fotos que se subieran, otra tabla para todos los comentarios que tuvieran todas las cuentas, otra tabla para todos los comentarios de todas las fotografías subidas... etc

Es decir, todo en plan general para no tener que crear tablas dinámicamente en la aplicación para cada usuario, etc

El esquema era algo así para que sea más facil verlo:



Bueno esto era una "chapuza" pero bueno se me pedía más detalle en la documentación del proyecto que no en el proyecto en sí.

Ahora voy a realizar el PFC sobre este trabajo, pero ampilándolo y mejorando lo que tenía.

Aparte de otras cosas que voy a introducir, como mensajes privados, álbums para tener las fotos, un blog en el tablon, etc....

La principal cosa es el diseño de la base de datos, que imagino que en una aplicación como esta que se supone va a tener grandes cantidades de usuarios, cada usuario grandes cantidades de fotos, comentarios, etc... Ese esquema es una aberración a la eficiencia para buscar los datos.

Lo que tengo en mente es que cada vez que se registra un usuario se le crean automáticamente la tabla "comentarioscuenta_idcuenta" donde "idcuenta" es el identificador de la cuenta.

Así mismo se crearía una tabla "fotoscuenta_idcuenta" para las fotos que suba esa cuenta, "albums_idcuenta" para los albums que tenga esa cuenta... etc

Esto haría que por cada usuario tengamos unas 5 o 6 tablas, pero imagino que aunque tengamos "miles de tablas" en la base de datos, la eficiencia sería enorme comparado con tener 6 tablas y millones de datos en cada una.

Si mi planteamiento es incorrecto o no está del todo bien, me gustaría que me dierais consejo con vuestra experiencia.


Otra duda que tengo, es en el ejemplo de los comentarios que tiene cada foto.

Lo lógico con este esquema, sería crear una tabla de comentarios por cada foto subida. Pero no se hasta que punto esto podría ser eficiente, ya que entonces tendríamos miles o millones de tablas, puesto que se espera tener miles o millones de fotografías subidas. Y habría fotos que no tendrían comentarios, u otras que tendrían pocos...

Entonces, ¿qué sería más eficiente? Crear una tabla para los comentarios que tengan todas las fotos subidas por un usuario (así solo habría tantas tablas como usuarios), o crear como he comentado antes, una tabla de comentarios por cada foto subida.


Un saludo y gracias por vuestro tiempo ;)

Stoya

los SGBBDD no están pensados para eso, dudo mucho que la eficiencia sea buena, están optimizados para tratar con tablas grandes. Lo de crear tantas tablas me parece una aberración.

Si quieres hacer un buen PFC busca documentación al respecto de cómo se optimizan las bases de datos, y si luego la enlazas para que lo podamos ver los demás mejor.

Pero no sé lo que te has fumado. Mira cualquier proyecto que use bases de datos, como los foros, cms, etc. y verás que no crean tablas dinámicamente. No he mirado ninguno, pero casi seguro que es así.


Nakp

pues la aberracion es crear 2 tablas que estan relacionadas logicamente pero no en la base de datos :P

fotos y comentarios fotos deberian estar relacionadas no? de 1 a muchos :P y ya que nos n:n no necesitas la tabla "relacionesfotos"

no hace falta crear muchas tablas para no tener muchos datos por tabla, es mejor tener muchos datos en cada tabla (asi eliminas la redundancia en tablas con distinto nombre) y sabiendo relacionarlas optimizarias tu sistema ;)
Ojo por ojo, y el mundo acabará ciego.

_LooSeR_

#3
Cita de: krith en  7 Febrero 2011, 01:28 AM
los SGBBDD no están pensados para eso, dudo mucho que la eficiencia sea buena, están optimizados para tratar con tablas grandes. Lo de crear tantas tablas me parece una aberración.

Si quieres hacer un buen PFC busca documentación al respecto de cómo se optimizan las bases de datos, y si luego la enlazas para que lo podamos ver los demás mejor.

Pero no sé lo que te has fumado. Mira cualquier proyecto que use bases de datos, como los foros, cms, etc. y verás que no crean tablas dinámicamente. No he mirado ninguno, pero casi seguro que es así.



No me he fumado nada... Simplemente se me había ocurrido que quizá fuera mejor tener 1.000 tablas con 1.000 datos cada una, que una tabla con 1.000.000 de datos, puesto que la gran mayoría de veces que se accede a datos, solamente se trabajaría con los de una de esas tablas.

No había trabajado con bases de datos a gran escala, por ello preguntaba si estaba bien el planteamiento. Aparte que se lo comenté a un profesor y me dijo que sí que para el manejo de grandes datos lo separara :S (También es cierto que no sé que grado de conocimiento tenía en esto porque no es el que enseña bbdd)
De todas formas gracias por la respuesta

Cita de: Nakp en  7 Febrero 2011, 01:50 AM
pues la aberracion es crear 2 tablas que estan relacionadas logicamente pero no en la base de datos :P

fotos y comentarios fotos deberian estar relacionadas no? de 1 a muchos :P y ya que nos n:n no necesitas la tabla "relacionesfotos"

no hace falta crear muchas tablas para no tener muchos datos por tabla, es mejor tener muchos datos en cada tabla (asi eliminas la redundancia en tablas con distinto nombre) y sabiendo relacionarlas optimizarias tu sistema ;)

Si bueno, ese esquema lo hice hace bastante tiempo y ni me había fijado que no estaba relacionado. Claramente estarán relacionadas tanto en la base de datos como al trabajar con ellas en la aplicación.

Lo de la tabla "relacionesfotos" era una tabla como por ejemplo en el tuenti o facebook para "etiquetados" donde se etiquetaba una persona en la foto. Y la tabla "fotos" estaba para guardar la info de las fotos y de la cuenta que las subía.
(Solo tenia los albumes fijos "etiquetadas" y "subidas")

Entonces es mejor tener una tabla "fotos" donde guarde todas las fotos subidas a la web, añadiendo el identificador del usuario que la subió como clave. A pesar de que el volumen sea enorme?

Y así con todos los mensajes privados, comentarios de tablones, etc. Una tabla de cada apartado para toda la red social?

Muchas gracias

Stoya

Es una sobrecarga lógica que no tiene sentido, no me resulta complicado pensar en un escenario en que no puedas hacer claves foráneas porque no sepas a que tabla van, lo que haría que fuera poco mantenible.

Internamente el SGBBDD puede fragmentar vertical u horizontalmente las tablas para ganar eficiencia, y seguramente puedas configurarlo para indicarle cómo quieres hacerlo, si crees que sabes hacerlo mejor que él.

Deberías echarle un vistazo a cosas como ésta: http://portal.acm.org/citation.cfm?id=1454227

Pero más general, las tripletas te dan igual, lo que tienes que ver es en aplicaciones generales cómo van las BBDD.

Luego guarda las referencias, que un PFC sin referencias es una patraña. Si tienes un blog o algo así puedes luego poner un resumen en el blog, eso siempre queda bien.

_LooSeR_

#5
Ok, gracias ;)

Es interesante el aporte, (no conocía ni la existencia de RDF, me he informado algo por wikipedia) al menos me he enterado de algo sobre por donde van los tiros en cuanto a eficiencia al hacer particionados de los datos y tal, que imagino es a lo que te refieres de como trabaja internamente el SGBBDD.

Estoy diseñando ahora decentemente la BBDD.

Tengo una pregunta, aver si me la podéis contestar.

Por un lado tengo la entidad "Foto" que tendría los atributos título, url, fecha.

Pero también cada foto es subida por un usuario, así que tenía puesto el atributo "idcuenta" como la cuenta que había subido la fotografía.

El caso es que como voy a crear otra tabla para los álbumes, en realidad esta relacion del usuario que la ha subido y la foto, la puedo poner ahí en esta tabla, diciendo que pertenece al álbum "Subidas".
(Creo que así es como lo tiene Tuenti por ejemplo, porque utiliza el tipo de album 1 para etiquetadas, tipo 2 para subidas y tipo 3 para albumes creados por el usuario)

Esto sería lo normalizado, pero cada vez que trabajo con fotos, tengo que saber título, url, fecha y idcuenta que la subió.

Entonces por quizá rapidez y facilidad al trabajar me vendría bien tener el campo "idcuenta" como clave foránea en la tabla "foto".

Podría ser un dato redundante si además luego añado esta relación en la tabla de álbums, o simplemente puedo omitir de la tabla albums el álbum "Subidas por X" ya que para dicho caso específico podría obtener las fotos de ese álbum directamente de la tabla "Fotos"


No sé si me he explicado bien, es sencilla la duda pero igual me he enrevesado un poco... :P  Gracias

_LooSeR_

#6
Bueno, he diseñado ya más o menos la base de datos y he sacado un diagrama E-R



Aver si me podéis dar vuestra opinión de que os parece...  :)

He quitado la tabla que tenía anteriormente como "infocuentas" que era como una ampliación de los atributos de la cuenta, ya que de normal solo se trabajaba con unos pocos.
Pero he decidido poner todo en una misma tabla, y luego desde la aplicación ya realizaré las funciones necesarias para obtener los datos que quiera.

El tema que haya comentarios a usuarios, a fotos, o los mensajes con 0-1 usuarios es porque he pensado en que deje el valor NULL cuando un usuario es eliminado (en vez de borrar sus mensajes y comentarios) y desde la apliación tendré esto en cuenta para mostrar el nombre como "Usuario eliminado" pero que se puedan ver los mensajes.

También lo he hecho en los mensajes "privados", para que si se borra un usuario que te había enviado un mensaje, no se te borre el mensaje, aunque si que te mostrará "Usuario eliminado" y no el nombre del que te venía (Que ya no existirá).

----------------------------------------

Tengo una duda, que ya no me acuerdo como se hacía.

En la tabla "amistades" por ejemplo, tengo "idcuenta1" e "idcuenta2", son la clave primaria, pero además no puede haber otra fila con los mismos valores pero invertidos.
E imagino que al tenerlo como ahora, si que me dejaría tener por ejemplo:

Idcuenta1 Idcuenta2
1              2
2              1

¿Cómo se indica para que no puedan repetirse de este modo?

---------------------------------------

Y otra duda, ¿sería recomendable introducir dentro de la clave primaria las claves foráneas?

Por ejemplo en la tabla "Fotos"  tengo el "idfoto" solamente como clave primaria.
Aunque con eso ya basta, sería mejor añadir "idcuenta"?


Un saludo y muchas gracias

mit

He leido masomenos lo que necesitas y los comentarios y puedo decirte un par de cosas:

1.- Las bases de datos se rigen bajo un mismo principio, ya sea a pequeña escala o a grande escala.
2.- Sobre si es recomendable usar claves foraneas en primarias, te digo una cosa, la claves van a ir comunmente donde sean necesarias.
3.- Tambien estan los indices para mejorar el rendimiento de las bases de datos.

Segun veo y entiendo de lo que lei sobre tus problemas, siento que te has saltado algunos pasos para el diseño de una base de datos.
Es que realmente cuando realizas tus diagramas de la base de datos, la normalizacion de las tablas, creeme que te arroja los resultados a las dudas que tienes.
Esto que te digo es en buen plan amigo, pero creeme que toda la teoria que se enseña para diseñar las bases de datos es mas que util ademas de necesaria para no perderte.
Tal vez no te ayude mi respuesta, bero bueno jeje  ;)

Saludos y suerte colega.