Saltar al contenido principal
LibreTexts Español

9.4: Apéndice D - Diseño de Bases de Datos y Partes de una Base de Datos

  • Page ID
    104965
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Fundamentos del diseño de bases de datos

    El primer paso en el proceso formal de diseño de bases de datos es identificar los propósitos principales a los que servirá la base de datos. Hay tres funciones que probablemente sean de interés para un historiador:

    • Gestión de datos
    • Vinculación de registro
    • Análisis agregado y reconocimiento de patrones.

    Si bien estas funciones no son mutuamente excluyentes, cada una se efectúa por consideraciones de diseño. Muchas veces no sabrás completamente lo que quieres hacer con la base de datos al inicio del proceso de diseño, que es idealmente el mejor momento para estar tomando estas importantes decisiones. Por lo tanto, la flexibilidad es otro concepto importante para recordar.

    Cada una de estas funciones es un objetivo que se puede lograr mediante la conformación de la base de datos en el proceso de diseño, y cada una requerirá que algunos elementos del diseño de la base de datos se lleven a cabo de manera específica, aunque de ninguna manera son mutuamente excluyentes. Y este último punto es importante, dado que la mayoría de los historiadores querrán tener acceso a toda la gama de funcionalidades que ofrece la base de datos, y probablemente se dedicarán a investigaciones que requerirán los tres tipos de actividad enumerados. O, para decirlo de otra manera, es poco probable que sepas con precisión qué es lo que haces con tu base de datos al inicio mismo del proceso de diseño, que es cuando se deben tomar estas decisiones. Es por esto que muchos historiadores diseñan bases de datos que maximizan la flexibilidad en lo que pueden utilizarlas más adelante en el proyecto (un objetivo viene al precio de la simplicidad del diseño).

    A veces los historiadores también utilizan la base de datos como recurso bibliográfico. Puede ser útil conectar notas de fuentes secundarias a fuentes primarias y rastrear estas conexiones en cualquier dirección.

    El poder de una base de datos relacional, que es el poder de vinculación de registros, está estrechamente asociado e incluso dependiente del diseño de la base de datos. La eficiencia y precisión están dictadas por la estructura de la base de datos y el modelo de datos. Cuanto más esperes realizar el conteo, el promedio, la suma u otras formas de agregación de tus datos, más pensamiento y esfuerzo debes poner en el diseño de tu modelo de datos y la aplicación de una capa de estandarización a tus datos.

    Modelos conceptuales de diseño de bases de datos

    Los dos modelos conceptuales de diseño de bases de datos se conocen como:

    1. El enfoque orientado a fuentes (a veces llamado enfoque orientado a objetos)
    2. El enfoque orientado al método.

    Estos dos enfoques son opuestos diametrales. Cada diseño de base de datos es un compromiso entre estos dos. No existe una base de datos perfecta y absoluta orientada a métodos, ni tampoco existe una base de datos perfecta y absoluta orientada a fuentes.

    El modelo de diseño de bases de datos orientado a fuentes requiere que todo lo relacionado con el diseño de la base de datos esté orientado a registrar hasta el último dato de las fuentes, omitiendo nada y, de hecho, convertirse en un proxy digital para el original. La información contenida dentro de las fuentes, y la forma de esa información, dicta completamente cómo debe estructurarse la base de datos.

    El ciclo de vida de una base de datos ideal orientada a fuentes se puede representar así:

    Ciclo de vida de la base de datos orientada a fuentes

    Los historiadores gravitan hacia este método porque coloca las fuentes en el centro del proyecto de base de datos. Sin embargo, la entrada de datos en una base de datos es una actividad que consume mucho tiempo; esto se agrava cuando se registra minuciosamente toda la información que existe en sus fuentes. En términos prácticos, debe tomar decisiones sobre qué información excluir de la base de datos, contrariamente a los principios del modelo Orientado a Fuente. Esto viola el papel de la base de datos como sustituto digital de sus fuentes pero al menos le permite realizar su investigación dentro de un período razonable.

    Un enfoque rigurosamente aplicado orientado a la fuente puede resultar en un diseño difícil de manejar cuando intenta acomodar cada pieza de información de su fuente, algunos de los cuales solo pueden ocurrir una vez. Es cierto que sí permite una mayor latitud en enfoques analíticos posteriores, por lo que las consultas no se limitan a la agenda inicial de investigación. Te permite el lujo de no tener que anticipar todas tus preguntas de investigación por adelantado, lo que el modelo orientado al método sí requiere. El modelo orientado a fuentes transmite la fuente (con todas sus rarezas e irregularidades) de una manera razonablemente confiable a la base de datos con una mínima pérdida de información: “todo” se registra (es decir, lo que se excluye lo hace por su elección consciente), y si después algo se vuelve interesante, no tienes que volver a la fuente para ingresar información que inicialmente no consideraste interesante. El modelo orientado a fuentes también le permite registrar información de la fuente “tal cual”, y le permite tomar decisiones sobre el significado más adelante, por lo que 'merc.' se puede registrar como 'merc.', y no expandirse a 'comerciante' o 'mercer' en el punto de entrada a la base de datos. 1

    Por el contrario, el ciclo de vida de la base de datos de modelos orientada a métodos podría representarse de una manera diferente:

    Ciclo de vida de la base de datos orientada a métodos

    Aquí el foco está en la función y la salida, más que en la naturaleza de la información misma. Por lo tanto, al elegir su modelo para tu base de datos, es absolutamente imperativo que sepas desde el principio exactamente qué querrás hacer con la base de datos —incluyendo qué consultas querrás ejecutar. No subestime la precisión que aquí se necesita; la base de datos requiere un alto grado de granularidad para realizar el análisis.

    Las bases de datos orientadas a métodos son más rápidas de diseñar, construir e ingresar datos; sin embargo, es difícil y requiere mucho tiempo desviarse de la función diseñada de la base de datos, para explorar nuevas líneas de investigación descubiertas.

    En última instancia, necesitará dirigir un rumbo medio entre los dos modelos, probablemente con una tendencia a inclinarse hacia el enfoque orientado a la Fuente. Cuando tome decisiones sobre qué información necesita de sus fuentes para ingresar a la base de datos, recuerde que sus necesidades pueden cambiar en el transcurso de un proyecto que podría llevar varios años. Si quieres poder mantener la máxima flexibilidad en tu agenda de investigación, entonces planea acomodar más información en el diseño de la base de datos que si tienes muy claro qué es lo que necesitas hacer y estás seguro de que nunca cambiará. Si no sabes si tus necesidades de investigación van a cambiar, errar por el lado de acomodar más información — no excluya la información sobre sirvientes o esclavos a menos que estés absolutamente seguro de que nunca querrás tratar a 'hogares con sirvientes' y 'hogares con esclavijos' como unidades de análisis; si no han ingresado esa información, entonces no estará ahí para consultar más adelante.

    Sin embargo, si tiene muy claro sus objetivos y está completamente familiarizado con las fuentes y no espera un uso a largo plazo de esta información, un modelo orientado a métodos puede ser útil, eficiente y mucho más rápido de usar. Si estás respondiendo algunas preguntas bien definidas y específicas, el modelo orientado al método tiene más sentido.

    Capas de la base

    Las bases de datos a menudo involucran varias etapas de trabajo antes de que puedan ser completamente utilizadas para el análisis. Esto se debe a que las bases de datos bien diseñadas organizan los datos en varias capas. El modelo 'Three Layer' de diseño de bases de datos sirve para ilustrar cómo la organización de diferentes tipos de datos dentro de una base de datos puede mejorar drásticamente el potencial analítico de esa base de datos. La Capa de Normalización en particular es aquella que los historiadores deben invertir tiempo y esfuerzo en desarrollar.

    Siempre debe ser capaz de identificar si un dato es de la fuente o si ha sido estandarizado de alguna manera por usted. En términos de estructura de base de datos, cada campo siempre pertenecerá a una sola capa, aunque las tablas pueden contener campos de cualquier combinación de capas.

    • La capa Source
      • Esta capa incluye las tablas y campos que contienen información tomada de la fuente y las formas de los datos que se han ingresado textualmente a partir del original. No se ha realizado ninguna adaptación de la información original en esta capa. Esto permite recuperar información que muestra lo que realmente dijo la fuente.
    • La capa de estandarización
      • Esta capa incluye las tablas y campos que contienen datos que ha adaptado para facilitar el análisis, e incluye datos donde se ha estandarizado la ortografía, donde se han ampliado las abreviaturas, dónde se usa un solo sistema de datación y así sucesivamente. Esta capa se puede crear en la etapa de diseño de la base de datos o más tarde, una vez completada la entrada de datos. Si ingresa datos estandarizados en el momento de la entrada de datos, entonces debe ser rigurosamente consistente en la forma en que ingresa sus formularios estandarizados (por ejemplo, siempre deletreando 'Thomas' de la misma manera), y debe documentar cómo ha estandarizado. Si la estandarización se realiza después de la entrada de datos como post-procesamiento, puede crear sus valores estandarizados globalmente en todo el cuerpo de datos; esto puede llevar mucho tiempo cuando se trata de mucha información que necesita ser estandarizada. Si es posible, el primer enfoque es casi siempre la mejor opción a tomar.
    • La capa de Interpretación o Enriquecimiento
      • Esta capa es opcional, mientras que las otras dos no lo son. En esta capa se encuentran datos y material de otra parte, no de las fuentes primarias. Esto puede incluir clasificación, interpretación o variables calculadas. Puede ser el medio de vincular varios componentes o trozos de información para crear un registro enciclopédico más grande. Muchas bases de datos de investigación no incluyen una capa de Interpretación.

    Por lo general, estas capas no salen por separado como colecciones discretas de datos. En la mayoría de los casos, los datos pertenecientes a las capas coexistirán dentro de tablas, pero dentro de campos separados dentro de las tablas: por ejemplo, podrías crear dos campos para 'ocupación' en la misma tabla que registra información sobre personas, en un campo perteneciente a la capa Source puedes registrar cómo es la ocupación presentado en la fuente, en el segundo campo perteneciente a la capa Normalización se puede registrar una versión estandarizada de la ocupación. La versión estandarizada se utilizará para realizar consultas y análisis, ya que será más fácil de encontrar.

    Un elemento H5P interactivo ha sido excluido de esta versión del texto. Puedes verlo en línea aquí:
    https://uta.pressbooks.pub/historicalresearch/?p=275#h5p-10

    Definiciones de bases de datos: tablas, campos, registros, valores, reglas y tipos de datos

    Harvey y Press proporcionan una definición de una base de datos:

    “Una base de datos es una recopilación de datos interrelacionados organizados de manera predeterminada de acuerdo con un conjunto de reglas lógicas, y está estructurada para reflejar las relaciones naturales de los datos y los usos a los que se van a poner, en lugar de reflejar las demandas del hardware y software”.

    Esta es una manera útil de describir tanto el contenido como el entorno de una base de datos. Dentro de la propia base de datos, sin embargo, hay una serie de 'cosas' diferentes, llamadas Objetos, que sirven a una variedad de funciones (estas incluyen tablas donde se almacenan los datos reales, consultas, interfaces de usuario, etc.). Por el momento nos concentraremos solo en el primero de estos objetos, las mesas, y veremos algunos de los términos relacionados con ellos.

    Hay cuatro elementos principales en cualquier tabla en una base de datos, y cada uno de estos tiene varios nombres:

    • Tabla (también conocida como Entidades)
    • Nombre de campo (también conocido como Nombre de atributo o Nombre de columna)
    • Campo (también conocido como Columna, Variable, Atributo) Este es el valor en el campo.
    • Registro (también conocido como Fila) La colección de todos los campos hace un registro.

    imagen

    Un elemento H5P interactivo ha sido excluido de esta versión del texto. Puedes verlo en línea aquí:
    https://uta.pressbooks.pub/historicalresearch/?p=275#h5p-11

    En cada base de datos, los datos se almacenan en tablas, y la mayoría de las bases de datos tendrán más de una tabla. Estas tablas tendrán relaciones entre ellas que conectan la información que contienen y, por lo tanto, serán 'relacionadas'. Las tablas se componen de campos (columnas) y registros (filas). Cada campo contiene un tipo de información, y para cada registro la información en ese campo será del mismo tipo.

    Claves primarias y foráneas

    Las claves primarias y foráneas sirven como anclajes para las conexiones entre tablas relacionadas. Las claves sirven para un propósito particular dentro de una tabla: generalmente no se utilizan para capturar información dibujada para las fuentes, sino que se utilizan para realizar un seguimiento de la información necesaria para que la base de datos sepa qué registros en una tabla están conectados a registros en una tabla relacionada.

    Una regla de diseño de bases de datos establece que 'cada registro completo debe ser único'. Con fuentes históricas, esto a veces puede ser un problema. A menudo la misma información aparece legítimamente varias veces en las fuentes, por ejemplo, cuando se nombra a un individuo como testigo de una serie de testamentos a lo largo de una década o la misma persona es detenida más de una vez. Para que los registros se adhieran al requisito de singularidad, es necesario garantizar que cada registro sea distinto; si la naturaleza de nuestra información histórica nos impide poder garantizar esto, nos vemos obligados a hacer trampa. Sorprendentemente, al hacerlo, conseguimos una serie de efectos útiles en el diseño de nuestras mesas.

    La manera más fácil de garantizar que cada registro sea único es agregar un campo en el que ingresemos (o dejar que la base de datos ingrese automáticamente) un identificador único, un valor que será diferente para cada registro agregado a la tabla. Por lo general, se trata de un número secuencial, como los valores en los diversos campos de ID en la base de datos de Personas y Autos. Un valor de número secuencial aplicado a cada registro asegurará por sí mismo que cada registro en su conjunto será único, ya que el valor de ID nunca se duplicará de un registro al siguiente.

    Este campo único sirve como campo Clave Primaria para una tabla, siendo este el campo que actúa como conector para el lado 'uno' de una relación uno a muchos. El campo que conecta el otro lado de la relación que existe en la tabla en el lado 'muchos' de la relación se conoce como la Clave Extranjera. Un campo de clave externa no contiene un valor único para cada registro: debido a que está en el lado muchos de las relaciones, es probable que el mismo valor de ID ocurra en más de un registro.

    Considere la base de datos de Personas y Autos:

    Mesa de persona:

    PersonID

    FirstName

    Apellidos

    DoB

    DoD

    Carrera

    Ubicación

    Género

    1

    Anthony

    Soprano

    22/1/1958

    15/11/2003

    Blanco

    Nueva Jersey

    Macho

    2

    John

    Nieve

    15/02/1998

     

    Blanco

    Invernalia

    Macho

    3

    Scarlett

    O'Hara

    16/5/1842

    3/10/1931

    Blanco

    Tara

    Hembra

    4

    Sherlock

    Holmes

    29/6/1859

    4/4/1940

    Blanco

    Londres

    Macho

    5

    George

    Jefferson

    1/1/1956

    20/12/2004

    Negro

    Nueva York

    Macho

    6

    Louise

    Jefferson

    3/3/1960

    10/8/2010

    Negro

    Nueva York

    Hembra

    7

    Laverne

    Cox

    7/5/1981

     

    Negro

    Nueva Jersey

     

    8

    Lucille

    Ricardo

    19/09/1930

    1/5/2004

    Blanco

    Nueva York

    Hembra

    9

    Ricky

    Ricardo

    10/1/1926

    20/1/1989

    Hispano

    Cuba

    Macho

    10

    Fred

    Mertz

    11/1/1905

    1/2/1975

    Blanco

    NYC

    Macho

    11

    Ethel

    Mertz

    11/5/1912

    30/6/1990

    Blanco

    Ciudad de Nueva York

    Hembra

                   

    Mesa de coche:

    PersonID

    CariD

    CarType

    CarMake

    CarModel

    CarColor

    1

    1

    Sedán

    Honda

    Accord

    Negro

    2

    2

    Coupé

    Honda

    Cívico

    Rojo

    3

    3

    SUV

    Nissan

    Rogue

    Blanco

    4

    4

    SUV

    Cadillac

    Explanada

    Plata

    5

    4

    SUV

    Cadillac

    Explanada

    Plata

    6

    5

    SUV

    Ford

    Escape

    Azul

    7

    6

    Convertible

    Volkswagen

    Golf

    Oro

    7

    8

    Sedán

    Ford

    Tauro

    Verde

    8

    7

    Sedán

    Pontiac

    Bonneville

    Aqua

    9

    7

    Sedán

    Pontiac

    Bonneville

    Aqua

               

    La relación es uno a muchos, una persona puede tener muchos autos, y la relación está conectada por el campo personID que está presente en ambas tablas. El campo PersonID es la Clave Primaria de la tabla Persona, siendo único en esa tabla. Se trata de una Llave Extranjera en la mesa del Auto, apareciendo varias veces. La misma personID aparecerá cada vez que un registro contenga un auto propiedad de esa persona (como es el caso de la persona 7).

    Al diseñar la base de datos, debe pensar qué campos aparecerán en sus tablas, y debe recordar identificar las claves primarias y foráneas para sus tablas. Cada tabla debe tener un campo Clave Primaria, un campo con el tipo de datos 'aut\ nonumber' que generará un valor único para cada nuevo registro que agregue. No todas las mesas tendrán un campo de Clave Extranjera, solo aquellas que están en el lado 'muchos' de una relación uno a muchos. Recuerde que el campo Clave Extranjera contendrá la misma información (es decir, los números de ID) extraída del campo que es la Clave Primaria para esa relación. Sin estos campos Clave, la base de datos es incapaz de gestionar correctamente la relación, lo que hace que la recuperación y análisis de la información sea prácticamente imposible.


    This page titled 9.4: Apéndice D - Diseño de Bases de Datos y Partes de una Base de Datos is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by Stephanie Cole, Kimberly Breuer, Scott W. Palmer, and Brandon Blakeslee (Mavs Open Press) via source content that was edited to the style and standards of the LibreTexts platform.